我有一个C ++ DLL,可以导出这样的方法:
extern "C" __declspec (dllexport) void ConvE(int type, const char* path, int b1, int b2, int b3, int b4, int b5)
{
FFileList file_list;
char temp_path[1024];
if(type == 1)
{
sprintf(temp_path,"%s*",path);
GetFindFileListWin(temp_path,".mrs",file_list);
file_list.RecoveryZipE(b1, b2, b3, b4, b5);
file_list.ConvertNameMRes2Zip();
}
else if(type == 2)
{
sprintf(temp_path,"%s*",path);
GetFindFileListWin(temp_path,".zip",file_list);
file_list.ConvertZipE(b5, b4, b3, b2, b1);
file_list.ConvertNameZip2MRes();
}
}
我正在将它调用到我的C#应用程序中:
[DllImport("Mrs.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void ConvE(int type, string path, int b1, int b2, int b3, int b4, int b5);
但每次我运行它时,它都会抛出错误 “尝试读取或写入受保护的内存这通常表示其他内存已损坏”
据我所知,我在C#中导入函数的方式有问题,但我真的不知道如何解决它。
编辑: 默认情况下,有一个Conv()与我的ConvE相同但没有5个整数,并且一个工作正常。 我让ConvE使用file_list.RecoveryZipE(),之前在调试时,它将我堆叠在一个名为RecvoeryCharE的方法内(我将它添加到我的代码中,你可以看一下)而且,那个是基于RecoveryChar()适用于Conv()。
RecoveryChar:
void RecoveryChar(char* pData,int _size)
{
if(!pData) return;
BYTE b,bh,d;
for(int i=0;i<_size;i++) {
b = *pData;
bh = b&0x07;
d = (bh<<5)|(b>>3);
*pData = d ^ 0xff;
pData++;
}
}
RecvoeryCharE:
void RecoveryCharE(char* pData, int _size, int b1, int b2, int b3, int b4, int b5)
{
if(!pData) return;
BYTE b;
for(int i=0;i<_size;i++) {
b = *pData;
b = (((((b >> b1) | (b << 5)) ^ b2) + b3) ^ b4) - b5;
*pData = b;
pData++;
}
}
我在调试C#app时遇到的最后一个例外:
编辑:再次调试后,它就停留在这里
RecoveryCharE( _fileheaderReader , _fileheaderReaderSize, b1, b2, b3, b4, b5 );
出于某种原因, b1 值始终为0。 似乎因为这个原因我得到了受保护的内存错误。
我所做的只是复制存在recoveryChar()和convertChar()的所有方法,并将值作为参数传递。
答案 0 :(得分:0)
我会探索这些事情:
您在C ++和C#方面的平台是什么?它们都是32位吗?两个64位?如果你有一个整数长度的混合,你可能会遇到错误的两种语言之间的参数传输问题。无论如何,最安全的选择是使用例如&#39; int32_t&#39;来指定确切的整数宽度。而不只是&#39; int&#39;
有些人建议在转换c ++&#39; char *&#39;时指定确切的编组程序。到c#&#39; string&#39;使用例如&#34; MarshalAs(UnmanagedType.LPStr)]字符串路径&#34;,请试试这个
最后添加一些&#34; printf-like&#34;调试C ++中的代码,将各个步骤(包括调用开始时)的所有值转储到调试控制台。您可以使用以下函数,该函数与printf一样使用,但输出到debuging控制台。
C ++中调试输出的代码示例:
inline void log_(const char *format, ...)
{
va_list args;
va_start(args, format);
char buffer[1000];
vsprintf(buffer, format, args);
OutputDebugStringA(buffer);
}