.net 为什么我会得到;检测到PinvokesTack不平衡“;对于这个简单的例子?

.net 为什么我会得到;检测到PinvokesTack不平衡“;对于这个简单的例子?,.net,pinvoke,extern,.net,Pinvoke,Extern,我正在创建一个非常简单的PInvoke示例: extern "C" __declspec(dllexport) int Add(int a, int b) { return a + b; } [DllImport("CommonNativeLib.dll")] extern public static int Add(int a, int b); return NativeMethods.Add(a, b); 但每当我调用上述NativeMethods.Addmethod时,我都会

我正在创建一个非常简单的PInvoke示例:

extern "C" __declspec(dllexport) int Add(int a, int b)
{
    return a + b;
}

[DllImport("CommonNativeLib.dll")]
extern public static int Add(int a, int b);

return NativeMethods.Add(a, b);
但每当我调用上述
NativeMethods.Add
method时,我都会得到以下托管调试助手:

检测到PinvokesTack不平衡 消息:调用PInvoke函数“CommonManagedLib!”!CommonManagedLib.NativeMethods::Add'使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配

然后调用以预期的返回值完成,但是出现MDA消息既烦人又令人担忧-我还没有完全理解PInvoke,但是从我读到的内容来看,我非常确定我的签名是正确的-我做错了什么

这都是在32位操作系统上完成的。

您需要使用这两种操作系统中的任何一种

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) ...

因为常规C函数的工作方式不同于Windows API函数;它们的“调用约定”不同,这意味着它们传递参数的方式不同。(错误中暗示了这一点。)

堆栈不平衡的原因可能是签名与其他调用约定不匹配。默认情况下,调用约定为stdcall。当您的调用约定为stdcall时,如果您希望调用方按照cdecl调用约定清理堆栈,则被调用方将清理堆栈。你可以找到更多

但如果你是因为签名而面对的,只需通过上面的链接

实际上,Cdecl和StdCall之间的区别在于,使用StdCall时,被调用方负责清除堆栈,而在Cdecl中,调用方负责清除堆栈。因此,当你调用一个期望Cdecl作为StdCall的函数时,你的堆栈将不会被清理,因此会发出警告。@ChrisWue:我只是做了一个波浪式的解释,而不是深入细节,但是,是的,这是最大的区别;谢谢(顺便说一句,这是StdCall,而不是StdDecl。)这解决了我在32位和64位操作系统上的问题,尽管OP只有32位。谢谢
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) ...