附加信息:试图读取或写入受保护的内存.这通常表明其他内存已损坏
本文关键字:内存 受保护 已损坏 其他 常表明 信息 读取 | 更新日期: 2023-09-27 18:15:49
我正在尝试将字节数组传递给c++ dll:
c++:extern "C" __declspec(dllexport) char* myfunction(byte bytes[])
{
char *byteschar = (char*)bytes;
//do somethings with it
return byteschar;
}
c#: [DllImport("mydll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl
,CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string myfunction(byte[] bytes);
但是当我调用myfunction
时我得到一个System.AccessViolationException
当我在没有调试器的情况下运行可执行文件时,它似乎工作良好
如果您希望在c#中分配缓冲区并在c++中填充,则方法略有不同。
你应该分配一种"非托管"缓冲区,传递给DLL,然后转换结果并释放缓冲区。这在C中是完全相同的方式,但是从托管环境中调用。
你的c++代码应该是这样的:
extern "C" __declspec(dllexport) void myfunction(char* buffer, int length)
{
//Fill buffer with something observing the maximum length of the buffer.
}
c#中DLL的签名应该是:
[DllImport("mydll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl
,CharSet = CharSet.Ansi)]
public static extern string myfunction(IntPtr buffer, Int32 length);
要从c#调用它,你应该这样做:
IntPtr unmanagedBuffer = Marshal.AllocHGlobal(100);
// Your Unmanaged Call
myfunction(unmanagedBbuffer, 100);
string yourString = Marshal.PtrToStringUni(unmanagedBuffer);
Marshal.FreeHGlobal(unmanagedBuffer);
如果你不想在你的应用中出现内存泄漏,不要忘记调用FreeHGlobal。在"try/finally"子句中保护这个是很有趣的。
另一个观察是字符串的编码。Uni的意思是统一码。如果您使用其他字符串表示,请检查是否有等效的PtrToStringXXX函数。
应该是:
extern "C" __declspec(dllexport) char* myfunction(unsigned char * bytes)
{
//do somethings with it
return bytes;
}