Я работаю над расширением Thunderbird, которое будет называть существующий код C# через посредника C++/CLR. Я попал в ловушку, которую можно воспроизвести, используя только C++/CLR DLL или прямую C DLL.char * теряется при возврате из C DLL в js-ctypes
Моя функция
__declspec(dllexport)char* strTest2()
{
char *p = "Hello World";
char buffer[200];
char *q = buffer;
strcpy_s(q,200,p);
return p;
}
Если я вернусь р, я получаю "Hello World" назад. Если я вернусь, я получаю мусор или зависание. Проверка p и q в отладчике показывает, что они оба содержат одни и те же данные.
Я вызываю функцию, используя этот js;
Components.utils.import("resource://gre/modules/ctypes.jsm");
var lib = ctypes.open("<path to DLL>");
var getStr = lib.declare("strTest2",
ctypes.default_abi,
ctypes.char.ptr);
var str = getStr();
alert(str.readStringReplaceMalformed());
lib.close();
В отладчике Mozilla, ул определяется как объект типа CDATA, и рыть вниз достаточно далеко показывает, что он, содержащий строку в каждом случае, хотя я не могу видеть, что это строка.
Документы для js-ctype говорят, что если что-то ссылается непосредственно на CData, то оно будет сохранено в живых. Но мне кажется, что это происходит неправильно.
Если я указываю большой «статический» буфер, такой как
char *r = "\0....\0";
затем использовать strcpy_s, чтобы скопировать текст в этот буфер и вернуть г, то строка приходит через. Если я использую DLL-проект, где он прямой C. Но если я попробую это с проектом C++/CLR DLL, я должен использовать его, чтобы иметь возможность использовать мой существующий код C#, а затем попытаться записать в жестко закодированный буфер, потому что программа сбой.
Так что есть три способа, которые я вижу в будущем;
- GET во время выполнения созданных строк сохраняться на переключаясь от C++/CLR для JS-ctypes,
- получить C++/CLR, чтобы позволить мне изменить статический buffer- без того, возникают проблемы с несколькими экземплярами,
- получить JS для предоставления буфера, который может заполнить C++/CLR.
Кто-нибудь знает, как получить один из них для работы?
Не пытайтесь Interop с кодом C до тех пор, пока вы написали правильный код C первого. Возвращаемые указатели на локальные переменные - это неопределенное поведение. –