从c#调用c++ DLL和访问冲突问题,我的选择是什么
本文关键字:问题 我的 选择 是什么 访问冲突 调用 c++ DLL | 更新日期: 2023-09-27 18:01:39
我有一个64位的c++ DLL,我没有代码。我有。h和。lib对应的文件。
我可以毫无问题地调用2个api。它们返回版本号。所以这告诉我DLL在我的应用程序中正确加载,一切都很好。
有问题的API接受const char *:
bool func(const char *a, const char *b, const char *c, const char *d, const char *e, int number);
我已经创建了一个c#包装器:
[DllImport(mDllName, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
private static extern bool func(string a,
string b,
string c,
string d,
string e,
int number);
我知道这个包装器是可以的,因为参数是文件名。如果我传入一个不存在的文件名,我得到一个从DLL生成的对话框,说文件名不存在。然而,这个函数崩溃了,"访问冲突读取位置0x3C"。
所以我的看法是我写的c#包装器没有问题。我知道c++ dll工作正常,因为我正试图将现有的工作c++应用程序转换为c#。c++应用程序已经使用了有问题的DLL。
那么这里可能发生了什么?我的看法是,也许在实际的DLL中有一个错误,但问题并不严重到足以在c++应用程序中呈现,因为也许内存没有像c#应用程序那样严格检查?
如果是这种情况,是否有任何设置我可以关闭检查内存不那么严格的c#?或者我的选择是什么,考虑到我没有也永远不会访问DLL的源代码。
进一步分析:我创建了一个简单的WIN32 64位DLL,它有这些api:
__declspec(dllexport) char *hello()
{
return "Hello from DLL !";
}
__declspec(dllexport) int number()
{
return 1979;
}
我有c#包装器如下:
[DllImport("MAFuncWrapper.dll", CharSet=CharSet.Ansi)]
public static extern string hello();
[DllImport("MAFuncWrapper.dll")]
public static extern int number();
我可以成功地调用number(),但试图调用hello()给我:
First-chance exception at 0x00000000774B4102 (ntdll.dll) in WindowsFormsApplication1.exe: 0xC0000374: A heap has been corrupted (parameters: 0x000000007752B4B0).
If there is a handler for this exception, the program may be safely continued.
p/invoke看起来很好,对应该封送为UnmanagedType.U1
的返回值取模。
没有神奇的开关可以用来抑制这个错误。你必须解决这个问题。
如果你有一个c++程序在调用函数时成功,而你的c#程序失败了,那么c#程序似乎在某些方面有所不同。消除差异来解决问题。
关于你在编辑中问的另一个问题,这是错误的:
[DllImport("MAFuncWrapper.dll", CharSet=CharSet.Ansi)]
public static extern string hello();
string
返回值导致编组程序调用返回指针上的CoTaskMemFree
。因此产生了错误。
您必须声明返回类型为IntPtr
并将其传递给Marshal.PtrToStringAnsi
。