[英]pInvokeStackImbalance MDA Warning and how to turn it off or fix it
[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相關的任何其他信息
/無關:
為什么使用自己的實現與庫的自綁定? 您可以使用:
DotNetZip - 在C#,VB,任何.NET語言中壓縮和解壓縮 - 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。
堆棧不平衡是因為您具有不匹配的調用約定或錯誤匹配的函數聲明。 如果zlib32
使用stdcall
調用約定,我會非常驚訝。 肯定是使用cdecl
。 在給出更堅定的建議之前,我想看看你的C ++聲明。
保持警告,因為它在您的代碼中發現錯誤,並修復錯誤匹配,無論它們是什么。
這里可能存在一個真正的問題,但我通常必須時不時地禁用所有托管調試助手,因為其中一些神奇地啟用了。 一定要檢查Debug | 例外節點,然后展開托管調試助手並確保禁用每個托管調試助手。
編輯:您將有更好的運氣替換P / Invoke與您為compress2
創建的C ++ / CLI包裝compress2
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.