首先解釋一下,托管DLL和非托管DLL的區(qū)別。狹義解釋講,托管DLL就在Dotnet環(huán)境生成的DLL文件。非托管DLL不是在Dotnet環(huán)境生成的DLL文件。
???? 托管DLL文件,可以在Dotnet環(huán)境通過 “添加引用” 的方式,直接把托管DLL文件添加到項(xiàng)目中。然后通過 Using? DLL命名空間,來調(diào)用相應(yīng)的DLL對(duì)象 。
??? 非托管DLL文件,在Dotnet環(huán)境應(yīng)用時(shí),通過 DllImport 調(diào)用。
?? C# 調(diào)用非托管DLL文件。DLL文件是用C語(yǔ)言編寫的。
托管DLL就是能夠在公共語(yǔ)言運(yùn)行庫(kù)(Common Language Runtime,簡(jiǎn)稱CLR)中能夠直接引用的,并且擴(kuò)展名為“DLL”的文件。具體所指就是封裝各種命名空間所在的DLL文件,如System.dll等。非托管DLL就是平常所的動(dòng)態(tài)鏈接庫(kù)等,其中就包括了封裝所有Windows API函數(shù)的DLL文件。各種非托管DLL中的函數(shù)在公共語(yǔ)言運(yùn)行庫(kù)中不能直接被調(diào)用,而需要經(jīng)過.Net框架提供的“平臺(tái)調(diào)用”服務(wù)后才可以。
“平臺(tái)調(diào)用”是.Net框架為Visual Basic .Net、Visual C#等.Net開發(fā)語(yǔ)言提供的一種服務(wù),用以在托管代碼中引入各種非托管DLL中封裝的函數(shù)(其中包括Windows API函數(shù))?!捌脚_(tái)調(diào)用”依賴于元數(shù)據(jù)在運(yùn)行時(shí)查找導(dǎo)出函數(shù)并封裝其參數(shù)。圖01公共語(yǔ)言運(yùn)行庫(kù)利用“平臺(tái)服務(wù)”調(diào)用非托管DLL中的函數(shù)的流程圖:

圖01:“平臺(tái)服務(wù)”的調(diào)用非托管函數(shù)的流程圖
在托管代碼中使用“平臺(tái)調(diào)用”服務(wù)調(diào)用非托管DLL中封裝的函數(shù)時(shí),“平臺(tái)服務(wù)”將依次執(zhí)行以下操作:?
1. 查找包含該函數(shù)所在的DLL文件。?
2. 如果找到,則將該DLL文件 加載到內(nèi)存中。?
3. 查找函數(shù)在內(nèi)存中的地址并將其參數(shù)推到堆棧上,并封送所需的數(shù)據(jù)。?
4. 將控制權(quán)轉(zhuǎn)移給非托管函數(shù)。 這樣整個(gè)函數(shù)調(diào)用完成。
在Visual Basic .Net中使用“平臺(tái)調(diào)用”服務(wù),申明Windows API函數(shù)主要有二種具體的實(shí)現(xiàn)方法:?
1. 使用DllImport特征類來申明Windows API函數(shù)。
2. 使用“Declare”語(yǔ)句來申明Windows API函數(shù)。
這二種方法雖有異曲同工之效,但在繁簡(jiǎn)上卻有很大差異,第一種方法申明過程比較復(fù)雜,很容易在申明Windows API函數(shù)時(shí)出錯(cuò),所以并不提倡。而第二種方法相對(duì)簡(jiǎn)單,并且又保存了以前Visual Basic中的很多語(yǔ)法,所以在平常時(shí)大都使用這種方法來申明Windows API函數(shù)。