为什么我会在这个简单的例子中得到“PInvokeStackImbalance”?

时间:2011-04-09 03:12:33

标签: .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.Add方法时,我都会得到以下托管调试助手:

  

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

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

这一切都在32位操作系统上。

2 个答案:

答案 0 :(得分:42)

您需要使用

[DllImport("CommonNativeLib.dll", CallingConvention = CallingConvention.Cdecl)]

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

因为常规C函数的工作方式与Windows API函数不同;他们的“召集惯例”是不同的,这意味着他们如何传递参数是不同的。 (这在错误中暗示过。)

答案 1 :(得分:1)

Stack Imbalance原因要么是签名不匹配,所以默认情况下调用约定调用约定是stdcall。当你的调用约定是stdcall时,callee清理堆栈,如果你想让调用者清理堆栈,请使用cdecl调用约定。你可以找到更多Here

但是如果你因签名而面对,只需通过以上链接即可  Solve Signature based Stack Imbalance issues using PInvoke extension