在我的名为“scandll.dll”的C ++ DLL中,我有以下功能
extern "C" __declspec(dllexport) void scanfile(char * returnstring)
{
strcpy(returnstring, "return string");
}
在我的C#代码中我正在做这个
[DllImport("scandll.dll", CharSet = CharSet.Ansi, SetLastError = true )]
public static extern int scanfile(ref IntPtr strReturn);
这是我用来从dll
获取值的方法public void Scan()
{
string filename = "";
IntPtr ptr = new IntPtr();
scanfile(ref ptr);//Here i get the error
filename = Marshal.PtrToStringAnsi(ptr);
}
我得到一个异常抛出“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”
我正在关注此链接
Calling C++ code from C# error using references in c++ ref in c#
任何帮助都将不胜感激。
由于
答案 0 :(得分:4)
您的C ++代码是错误的 - 它所做的只是更改已传递给它的指针的值以指向常量字符串。来电者对这一变化一无所知。
就像你这样做一样:
void MyCfunction(int number)
{
number = 3;
}
然后希望该函数的调用者能以某种方式在任何地方看到数字“3”。
你可以在C ++中做这样的事情:
void MyCFunction(char* pReturnString)
{
strcpy(pReturnString, "Hello, world");
}
但你还需要在C#端确保你提供了一个指向它的pReturnString的缓冲区。一种方法是使用StringBuilder执行此操作,然后使用C函数的C#声明采用如下参数:
[MarshalAs(UnmanagedType.LPStr)] StringBuilder returnString
在调用C ++函数之前,需要在StringBuilder中保留空间。
在现实生活中,像这样的C / C ++函数几乎总是需要一个额外的长度参数,这允许调用者告诉被调用者它允许复制到缓冲区的字符串的最大长度。关于长度是否包括终止\ 0的约定没有一致性,因此人们通常会小心运行直到缓冲区的末尾。
答案 1 :(得分:0)
memcpy ( destination, * source, size_t num );
尝试将此值分配给returnstring = "rturn name";