PinvokeStackImbalance 错误 (C#)

PinvokeStackImbalance error (C#)

我是 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,因此可用。

我该如何解决这个问题?

    public int SendMail(..., long smtpPortNo);

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

为什么这在 3.5 中没有生成诊断很难猜测,但它确实应该。也许你只是从来没有 运行 它带有启用了 MDA 的调试器。声明错误导致的堆栈损坏有自我修复的习惯,因此它不一定要在运行时爆炸。仍然是一个非常非常不健康的问题,可能会导致漂亮的 运行dom 代码执行。

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

但是,说真的,那部电话一定是你真正的解决办法。