日期:2014-05-16  浏览次数:21024 次

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类型算是整形吧,我在C++里面要返回的是一个字串类型是char * 的,需要用怎么转换吗?


你把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