C# 即使在外部代码c之后,名称也已损坏

C# 即使在外部代码c之后,名称也已损坏,c#,c++,dllimport,C#,C++,Dllimport,我在C++项目中包含了一个C++库,我调用了它的一个方法。 以前我有过题,然后读了关于外部C的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++: 如果我在DLLImport中使用

我在C++项目中包含了一个C++库,我调用了它的一个方法。

以前我有过题,然后读了关于外部C的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++:

如果我在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);

为什么在使用Exc C之后,我必须给出这个入口点来让事情正常工作。< /P> < P>装饰C++名称是<强>不<强>问题。它实际上是非常理想的,它会自动地避免您在C++代码被更改和函数签名被更改时不得不诊断非常困难的运行时崩溃。因为现在会出现不匹配,您会得到一个简单的“Procedure not found”错误消息,而不是一个无法诊断的损坏调用堆栈

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


当调用一个C++类的实例方法时,通常的错误是一个硬崩溃,通常被报告为Access违规事件。当实例方法试图通过无效的指针访问C++类的另一个实例成员时触发。只能正确地调用静态C++函数。由于您似乎没有触发异常(但),有一些提示,函数应该首先是静态的。< /p>您能显示C++方法声明吗?您只在头文件中使用ExtEng+C吗?从您所说的来看,您似乎在头文件中声明为extern C,但该对象仍然在.cpp中被编译为cpp(因此被破坏)。试着打开dll,看看是否公开了C原型。@MichaelCMS::可以在类方法中使用外部“C”吗?如果我们在头文件中使用外部C,则会出现错误。所以我们在实现中使用它。@jeroenh我已经更新了这个问题。你是说类方法吗?类方法名称总是被重写。C++方法不是静态的,是的,VisualStudio在C++调用方法和其他类方法中编写任何代码时崩溃。不,它不是VisualStudio崩溃。这是你的C++代码。现在应该有点明显了。否则,通过启用非托管代码调试很容易看到。我已经给了你答案,你必须写一个C++/CLI包装器,这样你就可以正确地构造C++对象。正如你所说的,“只有一个静态C++函数可以被正确调用”。现在我们已经做了C++静态的方法,但是我们仍然在得到问题。
[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);