【问题标题】:Unbalanced Stack!堆栈不平衡!
【发布时间】:2010-11-13 09:12:34
【问题描述】:

我已经编写了一个 VC++ dll。 dll中其中一个方法的声明如下:

extern "C" _declspec(dllexport)
void startIt(int number)
{
     capture = cvCaptureFromCAM(number);
}

我在使用 P/Invoke 的 C# 代码中使用此 dll。我声明如下:

[DllImport("Tracking.dll", EntryPoint = "startIt")]
        public extern static void startIt(int number);

我将代码中的函数称为:

startIt(0);

现在,当遇到这一行时,编译器会抛出这个错误:

A call to PInvoke function 'UsingTracking!UsingTracking.Form1::startIt' has 
unbalanced the stack. This is likely because the managed PInvoke signature does 
not match the unmanaged target signature. Check that the calling convention 
and parameters of the PInvoke signature match the target unmanaged signature.

我不明白为什么会抛出这个错误,因为托管代码和非托管代码中的签名是相同的。此外,在我的另一台机器上,相同的代码在 Visual Studio 中完美运行。所以,这让我认为抛出的错误是误导。

请帮忙。

谢谢

【问题讨论】:

  • 你的一台机器是 x86 而另一台是 x64 吗?
  • 不,两者都是 x86。只是那个运行Win7和其他XP

标签: c# visual-c++ dll pinvoke


【解决方案1】:

当您 p/调用外部函数时,使用的 calling convention 默认为 __stdcall。由于您的函数使用__cdecl 约定,因此您需要将其声明为:

[DllImport("Tracking.dll", EntryPoint = "startIt",
    CallingConvention = CallingConvention.Cdecl)]
public extern static void startIt(int number);

【讨论】:

  • 感谢工作!但是,我仍然想知道为什么它在 Win7 上工作时没有抛出同样的错误!
  • @James,它应该有,除非 Win7 在后台执行特殊管道以切换到正确的调用约定。
  • @James,你是在 Win7 上使用完全相同的 dll 还是在那里重新编译?
  • @Constatin 是的,我在 XP 上重建了它!
  • stdcallcdecl 之间的区别在于,stdcall 由被调用函数负责从堆栈中删除参数(通常与 RET x 一起移动 ESP x) 和cdecl 是调用者的责任。
【解决方案2】:

您的DllImport 属性中是否缺少CallingConvention=CallingConvention.Cdecl

【讨论】:

  • 这是我在调试此问题时遇到的问题(切换到 .NET 4 后)。如果不指定,stdcall 是默认值!
  • 在我将旧解决方案从 .NET 2 切换到 .NET 4 后,这也为我解决了)
【解决方案3】:

Constantin 和 Frederic Hamidi 就如何解决此问题已正确回答了这个问题。这可以帮助避免最终的堆栈溢出。我自己也被这个咬过好几次了。这里真正起作用的是 .NET 4 启用了一个托管调试助手,用于在 32 位 x86 机器(不是 64 位)上调试(不是发布)构建,检查错误指定的 p/invoke 调用。这篇 MSDN 文章详细说明了这一点:http://msdn.microsoft.com/en-us/library/0htdy0k3.aspx。 Stephen Cleary 在这篇文章中指出这一点值得称赞:pinvokestackimbalance -- how can I fix this or turn it off?

【讨论】:

    猜你喜欢
    • 2016-05-06
    • 2011-05-22
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2014-03-13
    相关资源
    最近更新 更多