纠结一个关于C# 调用C++DLL返回字符串的问题
C# 调用一个C++DLL中的一个如下接口:
版本一
extern “C” __declspec(dllexport) BOOL Func(char* s1,char** s2)
{
string rt = "xxxxx";
memcpy(*s2,rt.c_str(),rt.length());
return false;
}
C#调用:
[DllImport(“MyDLL.dll", EntryPoint=" Func",CharSet=CharSet.ansi)];
public static bool Func(string s1,ref string s2);
问题来了,调用的时候有时会出现dll中内存被破坏,感觉是memcpy(*s2,rt.c_str(),rt.length());貌似这句有问题。
换成版本二:
extern “C” __declspec(dllexport) BOOL Func(char* s1,char** s2)
{
string rt = "xxxxx";
*s2 = rt.c_str();
return false;
}
内存的问题解决了,但是C#一侧返回的s2是乱码,上网查了下 C++的string.c_str()的生命周期同其string一致,个人感觉是的dll中函数返回导致其字符串生命结束。有人说出乱码是编码集的问题,应为dll不是用的unicode。然后版本三:
extern “C” __declspec(dllexport) BOOL Func(char* s1,char** s2)
{
string rt = "xxxxx";
*s2 = malloc(rt.length + 1);
memset(*s2,0,rt.length + 1);
memcpy(*s2,rt.c_str(),rt.length);
return false;
}
这样dll不会报内存错误,返回的字符串也正常,但是dll中申请的内存却没有释放,然后实验了一个版本四:
extern “C” __declspec(dllexport) BOOL Func(char* s1,char** s2)
{
*s2 = "xxxxxx";
return false;
}
同版本3一样,没有出问题,然后我想问的是在这次调用中*s2的内存哪里来的,dll申请的还是C#呢,什么时候释放,
*s2 = "xxxxxx";这句话怎么理解,运行时将"xxxxxx"拷贝到*s2已经分配好的内存空间?那岂不是会有越界的风险,
而且C#那边连续重复调用这个接口 *s2的内容都是第一次返回的内容,但是地址确不一致。而且我看上一次*s2地址里的内容页还在,感觉没有释放,那*s2到底该怎么处理呢。