【问题标题】:PinvokeStackImbalance error (C#)PinvokeStackImbalance 错误 (C#)
【发布时间】:2015-12-07 18:31:12
【问题描述】:

我是 Pinvoke 的新手。

我有一个大型项目,它调用了一个名为 vtmail.dll 的 DLL。它在 .Net 3.5 中运行良好,但在升级到 .NET 4.0 时,我收到了 PinvokeStackImbalance 异常

调用代码有点像这样:

VTMail vtMail = new VTMail();
ec = vtMail.SendMail("servername",
   false,
   "",
   "",
   "Subject",
   "Sender Name",
   "sender@mydomain.com",
   "",
   "sendto@theirdomain.com",
   "reply@mydomain.com,
   "Description",
   "foldername",
   false,
   25);

检查 vtmail.dll 中的声明是这样的:

public int SendMail(string mailServer, bool login, string userName, 
                    string password, string subject, string fromName, 
                    string fromAddress, string toName, string toAddress, 
                    string replyToAddress, string bodyText, string folderToSend, 
                    bool encrypt, long smtpPortNo);

我对此进行了搜索,这似乎是一个已知的 .Net 4.0 问题。响应总是建议将CallingConvention=CallingConvention.Cdecl 添加到DllImport 语句中,但是这个特定的调用没有DllImport 语句,该dll 只是作为对Visual Studio 中项目的引用而添加的,因此可用。

我该如何解决这个问题?

【问题讨论】:

  • 这不是 .net 问题。这是您的代码的问题。你的代码有缺陷。遗憾的是,您没有显示足够的代码。您设法删除了所有重要的代码。我们需要完整的 C++ 和 C# 签名,以及参数语义的描述。
  • 您不能添加对非托管 DLL 的引用,可能您有一个对包含您正在寻找的 DllImport 属性的 .NET 包装 DLL 的引用。
  • P/Invoke 仅适用于非托管代码。如果您有对添加到项目中的 DLL 的引用,则它是托管 DLL。请将异常中的堆栈跟踪附加到您的问题中。据我们所知,异常可能是 vtmail.dll 中的一个错误
  • @theB 谢谢-我没有得到堆栈跟踪...只是一条消息说'对PInvoke函数'VTMail!MyNamespace.VTMail + VTMail32Dll :: VTMail'的调用使堆栈不平衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。即使包裹在try... catch 中,它也不会进入catch,只是在那条线上立即死亡。

标签: c# visual-studio-2010 dll .net-4.0 pinvoke


【解决方案1】:
    public int SendMail(..., long smtpPortNo);

最后一个论点不太可能是正确的。在 64 位 long 参数中存储必须小于 65536 的值完全没有意义。它肯定应该是 int 。一个经典的 Visual Basic 意外,VB.NET 之前的版本使用Long 声明一个 32 位整数。

为什么这在 3.5 中没有生成诊断,很难猜测,它当然应该。也许您只是从未使用启用了 MDA 的调试器运行它。由于声明错误导致的堆栈损坏具有自我修复的习惯,因此不一定要在运行时进行轰炸。尽管如此,这是一个非常非常不健康的问题,可能会导致非常随机的代码执行。

你可以做三件基本的事情。最重要的是使用电话,您希望这个库的作者修复他的错误。接下来是尝试翻转忽略位并关闭 MDA:Debug > Exceptions > Managed Debugging Assistants,取消选中“PInvokeStackImbalance”。我可能应该犹豫地提到新的 4.0 配置文件选项 <NetFx40_PInvokeStackResilience>

但是,真的,那部电话一定是你真正的解决方案。

【讨论】:

  • 采用了第二个有效的建议...之前尝试启用NetFx40_PInvokeStackResilience 无效,我可能无法很快联系到DLL的作者...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多