即使在extern c之后,也会出现混淆的名字

时间:2014-07-24 10:02:47

标签: c# c++ dllimport

我在C#项目中包含了一个C ++库,我正在调用其中一种方法。

早些时候我遇到了问题,然后阅读了关于extern c并将其应用于C ++方法。

然后尝试调用它如下:

[DllImport(@"F:\bin\APIClient.dll")]
public static extern IntPtr logIn2(IntPtr a, IntPtr b, IntPtr c, IntPtr d, IntPtr e, IntPtr f, int g);

但我仍然得到入口点例外。

C ++:

 APICLIENT_API char* logIn2(const char* a, const char* b,const char* c,const char* d,const char* e,const char* f, int g);

如果我在DLLImport中使用entryPoint,那么它可以正常工作:

[DllImport(@"F:\bin\APIClient.dll", EntryPoint = "?logIn2@CAPIClient@API@@QAEPADPBD00000H@Z", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr logIn2(IntPtr a, IntPtr b, IntPtr c, IntPtr d, IntPtr e, IntPtr f, int g);

为什么即使在使用extern c之后我也必须提供此入口点以使其正常工作。

1 个答案:

答案 0 :(得分:2)

装饰的C ++名称是一个问题。实际上非常需要它,它可以自动避免在更改C ++代码和更改函数签名时诊断非常困难的运行时崩溃。由于现在会出现不匹配的情况,您会收到一个简单的“找不到过程”错误消息,而不是一个完全无法识别的损坏的调用堆栈。

更大的问题,以及extern "C"不起作用的原因是,这是CAPIClient类的实例方法。它使用__thiscall调用约定,传递有效的 this 指针。你无法从pinvoke获得它,它需要为C ++对象分配内存并调用CAPIClient构造函数。只有C ++编译器知道如何正确地执行此操作,只有它知道要分配的正确内存量。所以你不能用pinvoke,你必须编写一个C ++ / CLI包装器。

当你对C ++类的实例方法进行pinvoke时,正常的事故就是硬崩溃,通常报告为AccessViolationException。当实例方法尝试通过无效的 this 指针访问C ++类的另一个其他实例成员时触发。只能正确地设置静态C ++函数。由于你似乎没有触发异常(还),所以有一些暗示该函数应该首先是 static