即使在extern c之后,名字也被弄乱了

Mangled name even after extern c

本文关键字:乱了 extern 之后      更新时间:2023-10-16

我已经在我的c#项目中包含了一个c++库,我正在调用它的一个方法。

早些时候,我有混乱的问题,然后阅读关于extern c并将其应用于c++方法。

然后试着像下面这样调用它:

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

但是我仍然得到Entry Point异常。

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:binAPIClient.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之后,我也必须给这个入口点使事情正常工作

修饰过的c++名称不是问题。这实际上是非常可取的,当c++代码发生变化和函数签名发生变化时,它可以自动地使您不必诊断非常困难的运行时崩溃。因为现在会有不匹配,你会得到一个简单的"Procedure not found"错误消息,而不是一个损坏的调用堆栈,这是相当不可诊断的。

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

当你调用一个c++类的实例方法时,通常的错误是硬崩溃,通常报告为AccessViolationException。当实例方法试图通过无效的this指针访问c++类的另一个实例成员时触发。只有静态c++函数才能被正确调用。因为你似乎还没有触发一个异常,这里有一些提示,函数应该是静态的放在第一位。