C# [ImportDll()] 知識小結(jié)
這周在做公司的一個C#項(xiàng)目中,要寫一個webservice提供一個下載方法,之前公司有過,但是要整改,于是這種鳥屎攤子又交給了我,其中一個密文流的下載中要應(yīng)用我們小組另一伙人用C++寫的四個dll, 這些DLL是由我們自己編寫的,非.NET 托管,這是一個麻煩事;
如果用 IDE往工程里add reference時,它會提示這幾個dll是沒有注冊的,不是.NET托管的。好吧,順便補(bǔ)充一下.NET托管和非托管。
具體官方術(shù)語是:
托管DLL就是能夠在公共語言運(yùn)行庫(Common Language Runtime,簡稱CLR)中能夠直接引用的,并且擴(kuò)展名為“DLL”的文件。具體所指就是封裝各種命名空間所在的DLL文件,如System.dll等。非托管DLL就是平常所的動態(tài)鏈接庫等,其中就包括了封裝所有Windows API函數(shù)的DLL文件。各種非托管DLL中的函數(shù)在公共語言運(yùn)行庫中不能直接被調(diào)用,而需要經(jīng)過.Net框架提供的“平臺調(diào)用”服務(wù)后才可以。
通俗點(diǎn)講就是:
托管Dll就在.NET環(huán)境生成的Dll文件。
非托管dll不是在.NET環(huán)境生成的dll文件。比如說用c寫的,用C++寫的。
托管Dll文件,可以在IDE通過 “add reference” 的方式,直接把托管Dll文件添加到項(xiàng)目中。然后通過 Using Dll命名空間,來調(diào)用相應(yīng)的Dll對象 。非托管Dll文件怎么調(diào)用了,這就要用到 [ImportDll()] 這種方法了;
[ImportDll()] 這種方法是通過P/Iovoke 來調(diào)用WIN32 API。其作用是導(dǎo)入外部的函數(shù),這些函數(shù)不是由NET托管的。當(dāng)然當(dāng)使用[ImportDll()] 時,必須要引入命名空間:
using System.Runtime.InteropServices;
舉一個例子
[DllImport(@("DownloadPlaintext.dll",EntryPoint="DownloadPlaintext"))] static extern Boolean FileDownLoad ([MarshalAs(UnmanagedType.LPStr)] StringBuilder pstrSourceFile, [MarshalAs(UnmanagedType.LPStr)] long lintFileSize, bool blnEnFlag)
這個例子導(dǎo)入的就是一個 C++寫的dll,名字是DownloadPlaintext.dll,這樣寫的是相對的路徑,所以我們必須要手動的把這個dll文件拷到該項(xiàng)目的bin目錄下對應(yīng)的release或者Debug目錄中去。否則就會找不到dll,或者直接將此dll,丟到system32中去,但這樣做是不安全的;
EntryPoint是外部函數(shù) 的入口點(diǎn),可以理解為調(diào)用外部函數(shù)的那個方法,假設(shè)dll中存在DownloadPlaintext這個函數(shù)名,而項(xiàng)目中也存在的話,這樣就會有沖突,所以C#還提供了重定義外部函數(shù)方法名,(并不是該dll中的名字,只是改變其在這個項(xiàng)目文件中的使用名而已),就像上面的例子一樣,將DownloadPlaintext方法在C#這個項(xiàng)目的使用名命名為FileDownLoad ,要注意的是參數(shù)要一致,類型要一致;
MarshalAs 是指提供向非托管代碼封裝數(shù)據(jù)時的規(guī)則,上面告訴net,第一個參數(shù)要用string 類型,第三個是bool型;
這里要注意一個問題,剛開始改代碼時,調(diào)試通過了,一發(fā)到IIS,其他人根本無法成功調(diào)用這個方法,我糾結(jié)了半天,后來才找到原因!
因?yàn)槭窃谇叭嘶A(chǔ)上改代碼,沒注意前人留下的坑,這份代碼的初始者,將dll的引入路徑做成的是絕對路徑:
[DllImport(@("C:\CloudDll\DownloadPlaintext.dll",EntryPoint="DownloadPlaintext"))]
這樣的話,IIS是無法去找到這個路徑的,即使你在C:\CloudDll目錄下有這個dll,所以,要專業(yè)點(diǎn)...
這個方法,看似是好簡單的東西,可是不深究的話是學(xué)不到東西的!
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
- C#調(diào)用C類型dll入?yún)閟truct的問題詳解
- C# 添加對System.Configuration.dll文件的引用操作
- 關(guān)于C#調(diào)用C++dll傳指針釋放內(nèi)存問題
- vs2019 實(shí)現(xiàn)C#調(diào)用c++的dll兩種方法
- C#中托管DLL和非托管DLL的區(qū)別詳解
- VSCode調(diào)試C#程序及附缺失.dll文件的解決辦法
- Qt程序中調(diào)用C#編寫的dll(推薦)
- C#調(diào)用Win32的API函數(shù)--User32.dll
- C#調(diào)用C++dll方法步驟
- C#如何通過probing指定dll尋找文件夾詳解
- C#調(diào)用易語言寫的Dll文件方法
- C#使用反射(Reflect)獲取dll文件中的類型并調(diào)用方法
- C# 嵌入dll 的方法
- c#調(diào)用c語言dll需要注意的地方
相關(guān)文章
C#實(shí)現(xiàn)六大設(shè)計(jì)原則之單一職責(zé)原則
這篇文章介紹了C#實(shí)現(xiàn)六大設(shè)計(jì)原則之單一職責(zé)原則的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02C#實(shí)現(xiàn)獲取計(jì)算機(jī)信息的示例代碼
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)獲取計(jì)算機(jī)軟硬件信息的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2024-01-01c# 共享狀態(tài)的文件讀寫實(shí)現(xiàn)代碼
開發(fā)中有時會遇到要對文件進(jìn)行共享狀態(tài)的讀寫操作,代碼如下,需要的朋友可以參考下2012-06-06