pinvokestack失衡MDA警告以及如何关闭或修复它
本文关键字:何关闭 失衡 MDA 警告 pinvokestack | 更新日期: 2023-09-27 17:50:25
[DllImport( "zlib32" )]
private static extern ZLibError compress2(
byte[] dest,
ref int destLength,
byte[] source,
int sourceLength,
ZLibQuality quality
);
每次调用时,我都会得到一个MDA警告,告诉我堆栈不平衡,这是调试的噩梦。我想要么关闭这个警告,要么修复这个问题
这个MDA会告诉您,您正在为PInvoke调用使用的参数类型有问题。一般来说,关闭是一个非常糟糕的主意,因为它会警告代码中的问题,并且不平衡的堆栈会导致将来的错误(有时很难找到)。
通常,常见的错误是选择非托管类型与托管类型匹配。
在您的情况下,原始定义(我看了看zlib125.zip):
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
,可以翻译为如果库被编译为64位支持unsigned long
:
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
也许您尝试使用为其他调用约定编译的库,例如
cdecl
而不是stdcall
也许你尝试使用修改的库,其中
compress2
函数需要额外的参数。
当我们看到你正在使用的确切的库时,我们可以发现哪里有问题。
long
或unsigned long
通常在Windows下为32位,分别映射到int
或uint
。由于您在原始声明中遇到麻烦,我假设您可能正在使用具有64位支持的特定库。感谢David Heffernan给我指出来,让我的注意更清晰。
您可以使用以下资源作为参考:
.NET开发人员的wiki - PInvoke.net主要是一个wiki,允许开发人员查找,编辑和添加PInvoke*签名,用户定义类型,以及与从托管代码调用Win32和其他非托管api相关的任何其他信息
PInvoke Interop Assistant
/顺便
为什么你要用你自己的实现和library的self绑定?你可以使用:
DotNetZip -在c#, VB,任何。net语言中压缩和解压缩- DotNetZip是一个易于使用,快速,免费的类库和工具集,用于操作Zip文件或文件夹。Zip和Unzip很容易:使用DotNetZip,用VB、c#(任何。net语言)编写的。net应用程序可以很容易地创建、读取、提取或更新Zip文件。
或准备使用7-zip绑定:SevenZipSharp -托管的7-zip库,用c#编写,提供数据(自)提取和压缩(所有7-zip格式都支持)。它包装7z.dll或任何兼容的一个,并使用LZMA SDK。
堆栈不平衡是因为调用约定不匹配或函数声明不匹配。如果zlib32
使用stdcall
调用约定,我会感到非常惊讶。当然使用cdecl
。在给出更确切的建议之前,我想看看你对该函数的c++声明。
保留警告,因为它会发现代码中的错误,并修复不匹配,无论它们是什么
这里可能有一个真正的问题,但我通常不得不不时禁用所有托管调试助手,因为其中一些神奇地启用了。一定要检查Debug | Exceptions节点,然后展开 Managed Debugging Assistants,并确保所有这些都被禁用。
EDIT:您将有更好的运气替换p/Invoke与您为compress2
创建的c++/CLI包装器