从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.

从c#调用c++ DLL和访问冲突问题,我的选择是什么

p/invoke看起来很好,对应该封送为UnmanagedType.U1的返回值取模。

没有神奇的开关可以用来抑制这个错误。你必须解决这个问题。

如果你有一个c++程序在调用函数时成功,而你的c#程序失败了,那么c#程序似乎在某些方面有所不同。消除差异来解决问题。


关于你在编辑中问的另一个问题,这是错误的:

[DllImport("MAFuncWrapper.dll", CharSet=CharSet.Ansi)]
public static extern string hello();

string返回值导致编组程序调用返回指针上的CoTaskMemFree。因此产生了错误。

您必须声明返回类型为IntPtr并将其传递给Marshal.PtrToStringAnsi