新手求问:C#调用C++dll函数时返回值的问题
这是在C++头文件里头的声明
C/C++ code
extern "C" __declspec(dllexport) char* __stdcall getb(char * str);
这是函数的定义
C/C++ code
char * __stdcall getb(char * str)
{
string strb(str);
char * xstr = (char *)strb.c_str();
return xstr;
}
这是C#里头函数导入的代码
C# code
public class Utility
{
[DllImport("bb.dll", EntryPoint = "_getb@4", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr getb(IntPtr inp);
}
这里是C#里调用函数的代码
C# code
string str = "AAAA";
IntPtr trb = Utility.getb(Marshal.StringToBSTR(str));
string b = Marshal.PtrToStringBSTR(trb);
觉得好奇怪,怎么调用函数的时候会提示异常:
未处理AccessViolationException
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
而且如果把函数定义改成直接返回参数的指针,就没有问题:
C/C++ code
char * __stdcall getb(char * str)
{
return str;
}
感觉应该是string里头出问题了吧~但是不知道错哪了,怎么修改,而且开始的想法不是只把char*放到string里头再得到char*,中间还有对那个string进行操作的。
请高手们帮忙找找错误~谢谢了~~
------解决方案--------------------
char * __stdcall getb(char * str)
{
string strb(str);
char * xstr = (char *)strb.c_str();
return xstr;
}
这样写有问题。
string strb(str);
strb创建在栈中,return xstr导致了strb的析构,strb中创建的字符串也随之丢失。
xstr指向strb创建的字符串,后果就是xstr指向已经释放的内存。
------解决方案--------------------
简单的,仅作传入参数用string,输出参数用StringBuilder。
[DllImport("bb.dll", EntryPoint = "_getb@4", CallingConvention = CallingConvention.StdCall)]
public static extern string getb(string str);
另LZ的C++写法不对,如可以返回std::string类型,不能返回指向函数内部临时变量的指针,这是危险的。