我正在创建一个非常简单的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位操作系统上。
答案 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