我正在研究Thunderbird擴展,它將通過C++/CLR中介調用現有的C#代碼。我碰到了一個可以使用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;
}
如果我回到P,我得到的 「Hello World」 回來。如果我返回q,我會得到垃圾或掛起。在調試器中檢查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調試器,STR被認定爲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可以填充的緩衝區。
有誰知道如何讓其中一個工作?
不要試圖用C代碼互操作,直到你第一次寫有效的C代碼。返回指向局部變量的指針是未定義的行爲。 –