对PInvoke函数[函数名称]的调用使堆栈失衡

Kcv*_*vin 2 c# c++ pinvoke unmanaged

我正在尝试使用PInvoke来调用非托管C++ DLL,我遇到了错误(见下文).使用depends.exe我可以在导出的函数列表中看到错位的名称,因此是奇怪的EntryPoint名称.虽然出现此异常,但如果我继续进行Step Over调试,则函数返回并ptr等于1并打印"成功".

我已经尝试了其他帖子中的一些建议,但没有任何效果.我认为这uint32_t是非常自我解释的.我已经尝试更改要使用的C#PInvoke签名long,ulong但是仍然抛出异常并且值ptr非常大.我也试过了属性的设置CharSet和ExactSpelling属性,DllImport但这似乎也没有用.

我的问题是,我在做什么导致异常,如果我不能/不应该忽略异常 - 如何做到这一点?

非托管C++

MyClass.h

class __declspec(dllexport) MyClass
{
public:
   uint32_t runCommand(uint32_t start);
};
Run Code Online (Sandbox Code Playgroud)

MyClass.cpp

uint32_t MyClass::runCommand(uint32_t start);
{
    uint32_t status = 1;
    return status;
}
Run Code Online (Sandbox Code Playgroud)

管理C#

P/Invoke签名

[DllImport("myClass.dll", 
           EntryPoint = "?runCommand@MyClass@myClass@@QAEII@Z", 
           CallingConvention = CallingConvention.Cdecl)]
public static extern UInt32 runCommand(UInt32 baseAddress);
Run Code Online (Sandbox Code Playgroud)

用法

public static void Do()
{
    UInt32 a = 0xA000;
    UInt32 ptr = runCommand(a);
    Console.Write("Success!");
}
Run Code Online (Sandbox Code Playgroud)

错误:

托管调试助手'PInvokeStackImbalance'检测到'C:\ Users ...\TestApp.vshost.exe'中存在问题.

附加信息:对PInvoke函数'TestApp!TestApp.CSMyClass :: runCommand'的调用使堆栈失衡.这很可能是因为托管PInvoke签名与非托管目标签名不匹配.检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配.

使用Visual Studio 2015和C#应用程序是.NET Framework 4.6.

Mr.*_*C64 5

调用约定不匹配,导致堆栈不平衡.

由于runCommand是一个成员函数的MyClass,用于它的调用约定是不 __cdecl,但__thiscall(注意,有一个隐含的" this"指针与C++类的非静态成员函数参数传递).

您可能希望从DLL中导出纯C接口函数(不是C++类成员函数)以进行P/Invoke,或者您可以使用C++/CLI在本机代码和托管代码之间构建一个微小的桥接层,包装您的用C++/CLI编写的.NET托管类中的C++本机类,并使用来自C#的托管类包装器.