[DllImport( "zlib32" )]
private static extern ZLibError compress2(
byte[] dest,
ref int destLength,
byte[] source,
int sourceLength,
ZLibQuality quality
);
每次我调用它时都会收到MDA警告,告诉我堆栈是不平衡的,这是调试的噩梦。我想要关闭此警告,或者解决问题
答案 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下的
long
或unsigned long
usually 32-bit,分别映射到int
或uint
。由于你有原始声明的麻烦我假设你可能正在使用64位支持的特定库。感谢David Heffernan指出我清楚地注意到了。
您可以使用以下资源作为参考:
A wiki for .NET developers - PInvoke.net主要是一个wiki,允许开发人员查找,编辑和添加PInvoke *签名,用户定义的类型以及与调用Win32和其他非托管API相关的任何其他信息。托管代码
/ 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会更好。