调用c++;来自c#的dll和访问冲突问题,我的选择是什么? 我有一个64位的C++ DLL,我没有代码。 我有相应的.h和.lib文件

调用c++;来自c#的dll和访问冲突问题,我的选择是什么? 我有一个64位的C++ DLL,我没有代码。 我有相应的.h和.lib文件,c#,c++,.net,dll,C#,C++,.net,Dll,我可以调用其中两个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, CallingConventi

我可以调用其中两个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中可能存在bug,但是问题不足以在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.

p/invoke看起来很好,对返回值进行模化,返回值应被封送为
UnmanagedType.U1

没有可以用来抑制此错误的神奇开关。你必须修复故障

如果你有一个C++程序在调用函数时成功,而C程序失败,那么C语言程序似乎在某种程度上是不同的。消除差异以解决问题


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

[DllImport("MAFuncWrapper.dll", CharSet=CharSet.Ansi)]
public static extern string hello();
字符串
返回值导致marshaller调用返回指针上的
CoTaskMemFree
。因此出现了错误


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

“对应封送为UnmanagedType.U1的返回值进行模化”是什么意思?请参阅我的编辑和进一步分析。我想不出来。为什么hello()函数现在可以工作?我正在编译我的C应用程序,目标是X64,我的Win32 DLL也是为X64编译的。我的意思是C++ >代码> BOOL 应该被编排为<代码> unMajdType。并且您的
hello
函数被错误地封送。不能像那样使用字符串返回类型。封送拆收器对返回的指针调用CoTaskMemFree。请不要一直更改问题。感谢您设法解决了这个问题…原来DLL依赖于其他一些我在目录中没有的数据文件。但是我是新手,所以我现在更聪明地知道如何从C++中正确调用C++的DLL函数,从C函数返回char *是非常不正常的,调用方不知道他是否需要释放字符串的存储。在这种情况下,您返回的是一个未在堆上分配的文本。否则,这种代码很可能会产生错误。总之,pinvoke封送员尝试支持通用大小写,并尝试释放字符串。卡布姆。