p/invoke 不平衡堆栈错误

Posted

技术标签:

【中文标题】p/invoke 不平衡堆栈错误【英文标题】:p/invoke unbalanced stack error 【发布时间】:2011-12-01 21:07:35 【问题描述】:

我有以下 C++ 函数和 C# p/invoke decleration:

//C#
[DllImport("capture.dll", EntryPoint = "setup")]
public static extern void captureSetup(int rr);

//C++
extern "C" 
    __declspec(dllexport) void setup(int rr)

但是我收到一个关于 p/invoke 不平衡堆栈的错误,这可能是由托管签名与非托管签名不匹配引起的。

谁能看出这有什么问题?

【问题讨论】:

您确定setup 使用C 调用约定吗? @EricJ。是的。在我添加 int 参数之前,这甚至可以正常工作。 C# 声明不应该是 Short 吗? @chris no,int 匹配 int,32 位,但 short 是 16 位 【参考方案1】:

这是调用约定不匹配。 C++ 代码默认使用 cdecl,但 C# 假定使用 stdcall。您需要使它们匹配,例如

[DllImport("capture.dll", EntryPoint = "setup", 
    CallingConvention = CallingConvention.Cdecl)]
public static extern void captureSetup(int rr);

【讨论】:

太棒了,效果很好(我会在 3 分钟内接受)。但是为什么 setup 没有参数时它可以正常工作? 在 cdecl 中,调用者清理堆栈。在 stdcall 中,被调用者清理堆栈。当没有参数时,没有人需要清理,调试助手也无法判断是否存在潜在的不匹配。 顺便说一句,还有另一个答案,没有删除讨论的int 的大小。一个 Windows,int 在 C++ 和 C# 中都是 32 位。那里没有问题。

以上是关于p/invoke 不平衡堆栈错误的主要内容,如果未能解决你的问题,请参考以下文章

P/Invoke 有时会导致 Win32 1008 错误与 StringBuilder 参数

“对 PInvoke 函数的调用使堆栈不平衡”

编组 LPSTR 和浮动时的不平衡堆栈

使用 P/Invoke 在托管和非托管回调链上引发异常

P/Invoke疑难杂症

C# P/Invoke:可变参数委托回调