萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> asp.net編程 >> 調用非托管dll常出現的bug及解決辦法

調用非托管dll常出現的bug及解決辦法

  C和C++有很多好的類庫的沉澱,在.NET中,完全拋棄它們而重頭再來是非常不明智的、也是不現實的,所以,我們經常需要通過Pinvoke來使用以前遺留下來的非托管的dll。就.NET中使用非托管的dll經驗而言,經常碰到的問題至少有兩個,它們都是通過在運行時拋出異常來體現的。

  1、試圖加載格式不正確的程序

  出現這種異常,通常是.NET應用程序的“目標平台”與非托管dll的平台不一樣。

  一般,在使用VS開發.NET的應用程序和類庫時,默認的目標平台為“Any CPU”,即會在運行時可根據CPU類型自動選擇X86或X64,擁有這樣的能力是因為.NET編譯後的程序集是基於IL的,在運行時,CLR才會將其JIT發射為X86或X64的機器碼。

  而C或C++編譯生成的dll就是機器碼,所以,其平台的決策是在編譯時決定的。通過編譯選項的設置,我們可以將C/C++項目編譯為X86的dll或者X64的dll。

  所以,在調用了非托管dll的.NET項目中,也需要將其目標平台屬性設為與非托管的dll的運行平台完全一致。通常遺留下來的非托管dll都是基於x86的,所以,在調用了這類非托管dll的.NET項目中,就將其目標平台屬性設為“X86”。

  可根據“項目->屬性->生成->目標平台”找到該設置:

調用非托管dll常出現的bug及解決辦法三聯

  2、無法加載dll,找不到指定的模塊

  運行調用了非托管的.NET應用程序有時會出現這種異常,可是比較郁悶的是,這種異常並不是在所有的電腦上都會出現,就經驗來說,它只是在少部分電腦上出現,而在絕大部分電腦上運行都是正常的。我們在開發語音視頻錄制組件MFile時,就遇到過這個問題,當時很是頭疼。

  如果出現這種情況,很大的可能就是那少部分電腦上沒有安裝VC++運行時(CRT),或者是CRT安裝不正確導致的。好用的解決方案有兩種:

  (1)在C盤下找到了下列文件:msvcm80d.dll、msvcp80d.dll、msvcr80d.dll、Microsoft.VC80.DebugCRT.manifest。把這幾個文件拷貝到目標機器上,放到運行目錄下或放到system32下,就可以了。

  注意,一般這幾個文件都有多個版本,位於不同的文件夾下,要觀察其文件夾的名稱:是x86還是x64的、是debug的還是release的、以及是否要MFC的,這些選擇要與非托管dll的信息一致。

  (2)如果有非托管dll的源碼,那就修改編譯選項,重新編譯一下:將/MD或/MDd 改為 /MT或/MTd,這樣就實現了對VC運行時庫的靜態鏈接,在運行時就不再需要上述幾個dll了。

copyright © 萬盛學電腦網 all rights reserved