从c#调用c ++ dll和访问问题,我的选择是什么?

时间:2015-07-09 03:03:03

标签: c# c++ .net dll

我有一个64位的C ++ DLL,我没有代码。 我确实有.h和.lib相应的文件。

我可以毫无问题地调用其中两个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的源代码。我真的想在c#中使用这个应用程序。

进一步分析: 我创建了一个简单的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.

1 个答案:

答案 0 :(得分:0)

p / invoke看起来很好,以返回值为模,该值应该被编组为UnmanagedType.U1

您无法使用魔术开关来抑制此错误。你必须解决这个问题。

如果你有一个C ++程序在调用函数时成功,并且你的C#程序失败了,那么C#程序似乎在某种程度上有所不同。删除差异以解决问题。

关于您在编辑中提出的其他问题,这是错误的:

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

string返回值导致marshaller在返回的指针上调用CoTaskMemFree。因此错误。

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