C# 调用C++ DLL提示“
尝试读取或写入受保护的内存。”
我要用C#调用C++的DLL(里面是关于DES加密的算法),但是调用是有时会报错提示“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
C#调用的代码:
[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern string desEncrypt2(string keyText, string plainText);
C++代码:
char *desEncrypt2(char *encryptedText, const char *plainText)
{
unsigned char buf[9];
char hex[17];
unsigned char longbuf[512+1];
char longhex[512*2+1];
memset(buf, 0, sizeof(buf));
memset(hex, 0, sizeof(hex));
memset(longbuf, 0, sizeof(longbuf));
memset(longhex, 0, sizeof(longhex));
strncpy((char *)longbuf, plainText, sizeof(longbuf)-1); //平台移植到2008的需要,strncpy->strncpy_s
int index;
for (index = 0; longbuf[index]; index += 8)
{
memcpy(buf, longbuf+index, 8);
DesEncrypt(key, buf);
for (int i=0; i < 8; i++)
sprintf(hex+2*i, "%02x", buf[i]);
memcpy(longhex+2*index, hex, 16);
}
strcpy(encryptedText, longhex);
return encryptedText;
}
很可能是strcpy(encryptedText, longhex);这句导致的,但是去掉直接返回longhex又是乱码。
我在网上找了很久,有说分配的内存空间没有释放,请问“unsigned char longbuf[512+1];char longhex[512*2+1];”,这两个要释放的吗?不是动态分配啊,我不大懂C++麻烦各位帮忙了。
另外,我用的是VS2010的平台
------解决方案--------------------for (index = 0; longbuf[index]; index += 8)
{
memcpy(buf, longbuf+index, 8);
DesEncrypt(key, buf);
for (int i=0; i < 8; i++)
sprintf(hex+2*i, "%02x", buf[i]);
memcpy(longhex+2*index, hex, 16);
}
for循环退出条件longbuf[index]有点问题
index可以取0,8,16,。。。,512
但是取到512时候还没推出循环,这边再改下估计就没问题了
------解决方案--------------------会不会是函数调用协议不一致啊
------解决方案--------------------参数类型不对??
------解决方案--------------------返回值必须是IntPtr类型,然后用下面代码取值
Marshal.PtrToStringAnsi(desEncrypt2("xxx","xxx"));
------解决方案--------------------
你把intptr理解成指针就行了,转换就用我上面的方法呀
------解决方案--------------------CONST CHAR* 对应的C#类型 是 StringBuilder 用这个试试
------解决方案--------------------IntPtr对应指针类型
19位的char * 对应20位的char[]
------解决方案--------------------[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern string desEncrypt2(IntPtr keyText, IntPtr plainText);
IntPtr keyText = Marshal.AllocHGlobal(2000);
IntPtr plainText = Marshal.AllocHGlobal(2000);
IntPtr result = Marshal.AllocHGlobal(2000);
用函数的时候就 result = desEncrypt2(keyTex