我正在研究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代码。返回指向局部变量的指针是未定义的行为。 –