pInvokeStackImbalance MDA警告以及如何关闭或修复它

时间:2011-04-16 15:06:44

标签: c# visual-studio-2010

    [DllImport( "zlib32" )]
    private static extern ZLibError compress2( 
                byte[] dest,
                ref int destLength, 
                byte[] source, 
                int sourceLength, 
                ZLibQuality quality 
            );

每次我调用它时都会收到MDA警告,告诉我堆栈是不平衡的,这是调试的噩梦。我想要关闭此警告,或者解决问题

3 个答案:

答案 0 :(得分:3)

此MDA提出告诉您,您在PInvoke调用中使用的参数类型存在问题。一般来说,将其关闭非常糟糕,因为它会警告代码中的问题,并且不均衡的堆栈会导致将来出现错误(有时很难找到)。

通常,选择与托管类型的非托管类型匹配的常见错误。

在您的情况下,原始定义(我看一下zlib125.zip):

ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
                                  const Bytef *source, uLong sourceLen,
                                  int level)); 

如果库是用unsigned long的64位支持编译的,可以将其转换为:

static int compress2(
    byte[] dest,
    ref ulong destLength,
    byte[] source,
    ulong sourceLength,
    int level)

确保ZLibQuality枚举基于int。对于这两个长度,您的错误可能是 int 而不是 ulong

正如David Heffernan所述,还有很多其他原因未能找到确切的一个原因,如果您仍然想知道,请将我们链接到实际用于开发的库。

  • 使用Visual C ++的传统编译原始库将导致您获得仅具有32位支持的库,因此您提供的原始定义是有效的,除非ZLibQuality枚举不是基于int < / p>

  • 也许您尝试使用为其他调用约定编译的库,例如cdecl而不是stdcall

  • 也许您尝试使用修改后的库,其中compress2函数需要其他参数。

当我们看到您正在使用的确切库时,我们可以找到错误。

  Windows下的

longunsigned long usually 32-bit,分别映射到intuint。由于你有原始声明的麻烦我假设你可能正在使用64位支持的特定库。感谢David Heffernan指出我清楚地注意到了。

您可以使用以下资源作为参考:

/ Offtopic:

为什么使用自己的实现与库的自绑定?您可以使用:

  • DotNetZip - Zip and Unzip in C#, VB, any .NET language - DotNetZip是一个易于使用,快速,免费的类库和工具集,用于处理zip文件或文件夹。 Zip和Unzip很简单:使用DotNetZip,用VB编写的.NET应用程序,C#(任何.NET语言)都可以轻松创建,读取,提取或更新zip文件。对于Mono或MS .NET。

  • 或准备使用7-zip绑定:SevenZipSharp - 用C#编写的托管7-zip库,提供数据(自我)提取和压缩(支持所有7-zip格式)。它包装7z.dll或任何兼容的,并使用LZMA SDK。

答案 1 :(得分:1)

堆栈不平衡是因为您具有不匹配的调用约定或不匹配的函数声明。如果zlib32使用stdcall调用约定,我会感到非常惊讶。当然使用cdecl。在给出更坚定的建议之前,我想看看你对该函数的C ++声明。

保持警告,因为它在您的代码中发现错误,并修复错误匹配,无论它们是什么。

答案 2 :(得分:0)

这里可能存在一个真正的问题,但我通常不得不每隔一段时间禁用所有托管调试助手,因为其中一些神奇地启用了。一定要检查Debug |例外节点,然后展开托管调试助手,并确保其中每一个都被禁用。

编辑:使用您为compress2创建的C ++ / CLI包装器替换P / Invoke会更好。