呼叫非託管dll常出現的bug及解決辦法

2021-06-28 10:43:58 字數 1113 閱讀 4991

**

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」。

可根據「專案->屬性->生成->目標平台」找到該設定:

2、無法載入dll,找不到指定的模組

如果出現這種情況,很大的可能就是那少部分電腦上沒有安裝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了。

託管呼叫非託管的DLL

dllimport createnewprocess.dll charset charset.unicode public static extern bool createprocess marshalas unmanagedtype.lpwstr string fullpath 以上是定義入口,...

託管非託管Dll動態呼叫

最近經常看到有人問託管非託管 dll呼叫的問題。對於動態庫的呼叫其實很簡單。網上很多 都實現了 dll的靜態呼叫方法。我主要談論下動態庫的動態載入。對於託管動態庫,實現動態載入很簡單。files dwwwing dlldemo.rar code assembly.loadfile filepath ...

C 呼叫託管DLL與非託管DLL

dll之前使用過幾次,但是最近使用時,又出各種問題。最後弄到晚上十二點多了,看到網上乙個建立dll的 教程,按上面的講解,成功實現了c 呼叫自己建立的dll。之所以耗了這麼久時間,是因為我本想憑自己記憶實現dll建立呼叫,但是各種問題隨即產生。不說了,割了 今天上午再次整理,覺得有必要記錄。c 呼叫...