从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误
生活随笔
收集整理的這篇文章主要介紹了
从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
從.NET1.1升級(jí)到.NET2.0時(shí)出現(xiàn)的PInvokeStackImbalance錯(cuò)誤 微軟官方的解釋(http://msdn2.microsoft.com/zh-cn/library/0htdy0k3.aspx) 如果 CLR 檢測(cè)到平臺(tái)調(diào)用之后的堆棧深度與 DllImportAttribute 屬性指定的調(diào)用約定中以及托管簽名的參數(shù)聲明中提供的預(yù)期堆棧深度不匹配,則將激活 PInvokeStackImbalance 托管調(diào)試助手 (MDA)。 ? 下面將舉一個(gè)具體的例子 PCCamera類(lèi)(UserLib.Device.PCCamera攝像頭類(lèi))在從.NET1.1升級(jí)到.NET2.0時(shí)出現(xiàn)的PInvokeStackImbalance錯(cuò)誤: 檢測(cè)到 PInvokeStackImbalance Message: 對(duì) PInvoke 函數(shù)“WindowsApplication1!UserLib.Device.PCCamera::SendMessage”的調(diào)用導(dǎo)致堆棧不對(duì)稱(chēng)。原因可能是托管的 PInvoke 簽名與非托管的目標(biāo)簽名不匹配。請(qǐng)檢查 PInvoke 簽名的調(diào)用約定和參數(shù)與非托管的目標(biāo)簽名是否匹配。 錯(cuò)誤首次發(fā)生在這一行代碼: SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0); 經(jīng)過(guò)分析發(fā)現(xiàn)所有調(diào)用SendMessage函數(shù)的地方都會(huì)出現(xiàn)以上錯(cuò)誤 于是查看DLLImport: [DllImport("User32.dll")] private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, long lParam); 原來(lái)是因?yàn)閃inAPI的long類(lèi)型是32位的,而C#的long是64位的,這就導(dǎo)致堆棧不對(duì)稱(chēng),引發(fā)錯(cuò)誤. ? 原因:(http://discuss.develop.com/archives/wa.exe?A2=ind0512c&L=dotnet-winforms&D=0&T=0&P=8094) 在.NET2.0中加入了MDA(managed debugging assistant), 在平臺(tái)調(diào)用時(shí)后會(huì)檢查棧的指針, 如果發(fā)現(xiàn)不平衡, 就會(huì)拋出PInvokeStackImbalance異常; 而在.NET1.1中不會(huì)檢查, 所以不會(huì)捕獲到異常, 但在運(yùn)行時(shí)會(huì)導(dǎo)致不穩(wěn)定. ? 解決方法: 將最后一個(gè)”long lParam” 改為 “int wParam”, 因?yàn)?/span>C#中int是32位的. 并且將之后有涉及到SendMessage函數(shù)的參數(shù)適當(dāng)?shù)剞D(zhuǎn)成int型就可以了. 但是, 之后查閱了資料http://www.pinvoke.net/default.aspx/user32/SendMessage.html 發(fā)現(xiàn)先前的解決方案還有不合適的地方, 應(yīng)該將其中的 ”wParm” 和 ”lParm” 參數(shù)的類(lèi)型都轉(zhuǎn)成IntPtr類(lèi)型,并且將后面涉及到的參數(shù)的 ”0” 改為 “IntPtr.Zero”. 因?yàn)槿绻褂?/span>int類(lèi)型,那么這段代碼在64位的Windows上面將會(huì)無(wú)法正常運(yùn)行. ? 總結(jié): ?????? 我們?cè)谡{(diào)用WinAPI時(shí)要特別小心, 因?yàn)?/span>WinAPI和C#的數(shù)據(jù)類(lèi)型不是完全一樣, 就好像在WinAPI中的long類(lèi)型在C#中就是int類(lèi)型, 如果沒(méi)有處理好類(lèi)型問(wèn)題, 就很可能會(huì)導(dǎo)致堆棧的不平衡,引發(fā)PInvokeStackImbalance錯(cuò)誤, 但是這類(lèi)錯(cuò)誤在.NET1.1下不會(huì)被暴露出來(lái), 所以在從.NET1.1升級(jí)到.NET2.0時(shí)要特別注意此類(lèi)問(wèn)題.
轉(zhuǎn)載于:https://www.cnblogs.com/symbol441/archive/2007/11/02/946945.html
總結(jié)
以上是生活随笔為你收集整理的从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: reporting Server組件不全
- 下一篇: sed linux 命令