如果你是程序員,你會知道你需要用函數(shù)庫或者類庫來編程。也就是說,通常庫是程序的有機組成部分,可以靜態(tài)鏈接(。lib,在使用之前。lib,參考頭文件。h對應(yīng)于程序源代碼中的lib并在編譯時直接添加到源文件中)或者動態(tài)鏈接(DLL,程序運行時加載)作為程序的一部分。
在Windows中,許多應(yīng)用程序并不是一個完整的可執(zhí)行文件,它們被分割成一些相對獨立的動態(tài)鏈接庫,即DLL文件,放置于系統(tǒng)中。當(dāng)我們執(zhí)行某一個程序時,相應(yīng)的DLL文件就會被調(diào)用。一個應(yīng)用程序可使用多個DLL文件,一個DLL文件也可能被不同的應(yīng)用程序使用,這樣的DLL文件被稱為共享DLL文件。如在 Windows操作系統(tǒng)中,每個程序都可以使用該 DLL 中包含的功能來實現(xiàn)“打開”對話框。這有助于促進代碼重用和內(nèi)存的有效使用。通過使用 DLL,程序可以實現(xiàn)模塊化,由相對獨立的組件組成。MS把所有的API函數(shù)是放在幾個大的*.LIB中,另外還提供一對應(yīng)的幾個*.inc,實際上它如同*.h頭文件,起到聲明API函數(shù)的目的。DLL是動態(tài)鏈接庫的縮寫,意思是動態(tài)鏈接庫。在Windows中,很多應(yīng)用程序都不是一個完整的可執(zhí)行文件。分為一些相對獨立的動態(tài)鏈接庫,也就是DLL文件,放在系統(tǒng)中。當(dāng)我們執(zhí)行某個程序時,會調(diào)用對應(yīng)的DLL文件。一個應(yīng)用程序可以有多個動態(tài)鏈接庫文件,一個動態(tài)鏈接庫文件可以由幾個應(yīng)用程序共享。這樣的DLL文件叫做共享DLL文件。一般DLL文件存儲在C:WindowsSystem目錄下。
DLL文件存儲各種程序的函數(shù)(子過程)。當(dāng)一個程序需要調(diào)用一個函數(shù)時,需要先加載DLL,然后獲取函數(shù)的地址,最后調(diào)用。使用DLL文件的好處是程序在運行開始時不需要加載所有代碼,只在程序需要的時候從DLL中取出一個函數(shù)。此外,使用動態(tài)鏈接庫文件也可以減少程序的大小。
Windows系統(tǒng)平臺上,你可以將獨立的程序模塊創(chuàng)建為較小的DLL(Dynamic Linkable Library)文件,并可對它們單獨編譯和測試。在運行時,只有當(dāng)EXE程序確實要調(diào)用這些DLL模塊的情況下,系統(tǒng)才會將它們裝載到內(nèi)存空間中。這種方式不僅減少了EXE文件的大小和對內(nèi)存空間的需求,而且使這些DLL模塊可以同時被多個應(yīng)用程序使用。Microsoft Windows自己就將一些主要的系統(tǒng)功能以DLL模塊的形式實現(xiàn)。例如IE中的一些基本功能就是由DLL文件實現(xiàn)的,它可以被其它應(yīng)用程序調(diào)用和集成。一般來說,DLL是一種磁盤文件(通常帶有DLL擴展名,是標(biāo)準(zhǔn)win32可執(zhí)行文件-“PE”格式),它由全局?jǐn)?shù)據(jù)、服務(wù)函數(shù)和資源組成,在運行時被系統(tǒng)加載到進程的虛擬空間中,成為調(diào)用進程的一部分,進程中所有線程都可以調(diào)用其中的函數(shù)。如果與其它DLL之間沒有沖突,該文件通常映射到進程虛擬空間的同一地址上。DLL模塊中包含各種導(dǎo)出函數(shù),用于向外界提供服務(wù)。Windows在加載DLL模塊時將進程函數(shù)調(diào)用與DLL文件的導(dǎo)出函數(shù)相匹配。在系統(tǒng)的組策略和注冊表中,我們可以修改一些鍵值來優(yōu)化我們的系統(tǒng),加強操作系統(tǒng)的安全性。但是對于限制下載、禁止刪除文件等功能,我們無法完成這些操作,只能通過修改系統(tǒng)DLL文件來完成。目前通過修改系統(tǒng)的DLL文件,可以實現(xiàn)禁止刪除文件、禁止IE下載、禁止IE另存為、禁止文件打開方式等功能。
2 為什么要用DLL為什么把DLL封裝成函數(shù),這可能是系統(tǒng)中廣泛使用DLL的原因?
(1)擴展應(yīng)用
因為DLL可以被應(yīng)用程序動態(tài)加載到內(nèi)存中。所以應(yīng)用可以在需要的時候把DLL加載到內(nèi)存中,使得程序的可維護性非常高。比如QQ的視頻功能需要升級,負責(zé)編寫QQ的程序員不需要重寫QQ的所有代碼,只需要重寫視頻功能相關(guān)的DLL文件即可。
②方便程序員之間的合作
這與最終用戶關(guān)系不大,僅供理解。大家都知道編程工具很多,比如VB,VC,Delphi等。如果幾個人合作寫一個大程序,那么可能有人用VB,有人用VC,每個人用的編程語言都不一樣。應(yīng)該在哪個編譯器中編譯?就像一群來自不同國家的人一起寫一篇文章。如果他們使用不同的語言,寫出來的文章怎么會在一起?有了DLL,VC程序員就可以寫一個DLL,然后VB程序員就可以在程序中調(diào)用,不用擔(dān)心如何把它們編譯成單個的EXE。
③節(jié)省內(nèi)存
如果多個應(yīng)用程序調(diào)用同一個DLL,DLL文件不會重復(fù)加載到內(nèi)存中,但是加載到內(nèi)存中的同一個DLL會被這些應(yīng)用程序共享。就像在辦公室里,每個員工很少配備飲水機,而是在公共場所放置飲水機。所有需要用水的員工都可以共用這個飲水機,降低了成本,節(jié)約了空。
④共享節(jié)目資源
包括剛才提到的通用文件對話框,DLL文件提供了應(yīng)用之間共享資源的可能性。資源可以是程序?qū)υ捒颉⒆址?、圖標(biāo)或聲音文件。
⑤解決應(yīng)用本地化問題
下載一個程序的中文包,打開中文描述后,經(jīng)??梢钥吹匠绦虻脑糄LL被下載包中的DLL文件覆蓋,中文版完成。這些程序是與執(zhí)行代碼和應(yīng)用程序接口分開編寫的,所以Chinesizer只需要將程序接口相關(guān)的DLL進行漢化和發(fā)布即可。
3 隱式鏈接和顯式鏈接DLL文件中應(yīng)用導(dǎo)入函數(shù)和導(dǎo)出函數(shù)的鏈接方式有兩種:隱式鏈接和顯式鏈接。
加載時動態(tài)鏈接意味著應(yīng)用程序中不需要指明DLL文件的實際存儲路徑,程序員也不需要關(guān)心DLL文件的實際加載(編譯器自動完成地址分配)。通過使用隱式鏈接方法,當(dāng)程序員創(chuàng)建一個DLL文件時,鏈接器會自動生成一個相應(yīng)的LIB導(dǎo)入文件。該文件包含每個DLL導(dǎo)出函數(shù)的符號名和可選標(biāo)識號,但不包含實際代碼。LIB文件被編譯到應(yīng)用程序項目中,作為DLL的替代。程序員通過靜態(tài)鏈接編譯生成應(yīng)用程序時,應(yīng)用程序中的調(diào)用函數(shù)與LIB文件中導(dǎo)出的符號相匹配,這些符號或標(biāo)識號進入生成的EXE文件。LIB文件還包含相應(yīng)的DLL文件名(但不是完整的路徑名),由鏈接器存儲在EXE文件中。當(dāng)應(yīng)用程序在運行過程中需要加載一個DLL文件時,Windows根據(jù)這個信息發(fā)現(xiàn)并加載DLL,然后通過符號名或標(biāo)識號動態(tài)鏈接DLL函數(shù)。我們使用的大部分系統(tǒng)dll都是這樣鏈接的。如果找不到所需的Dll,將會給出一條錯誤消息,說明該Dll丟失。
運行時動態(tài)鏈接則相反。用戶程序沒有指出編譯時需要哪些dll,而是在運行后調(diào)用Win32的LoadLibary()函數(shù)加載dll。如果沒有找到Dll,這個函數(shù)將返回一個錯誤。在用LoadLibary()函數(shù)加載了Dll之后,應(yīng)用程序還需要使用GetProcAdress()函數(shù)來獲取Dll輸出函數(shù)的地址。顯式鏈接適用于集成開發(fā)語言。有了顯式鏈接,程序員不再使用導(dǎo)入文件,而是直接調(diào)用Win32的LoadLibary()函數(shù),并將DLL的路徑指定為參數(shù)。還有一點需要注意的是,knowdlls確保了當(dāng)通過LoadLibary()加載系統(tǒng)dll時,它只從特定的系統(tǒng)目錄加載,以防止加載錯誤。加載時會檢查注冊表下是否有相同的注冊表項名稱。
應(yīng)用程序如何找到動態(tài)鏈接庫文件
如果應(yīng)用程序使用LoadLibrary顯式鏈接,那么可以在這個函數(shù)的參數(shù)中指定DLL文件的完整路徑。如果您沒有指定路徑或建立隱式鏈接,窗口將按照以下搜索順序定位該動態(tài)鏈接庫:
I 包含EXE文件的目錄,II 進程的當(dāng)前工作目錄,III Windows系統(tǒng)目錄,IV Windows目錄,V 列在Path環(huán)境變量中的一系列目錄。在Windows上,有決定dll搜索順序的注冊表項:hklmsystemcurrentcontrolsetsessionmanager safedlsearchmode。該值在windows 7 server 2003 XP SP2中為1,在XP 2000 sp4中為0。
1,搜索順序是:1??蓤?zhí)行文件所在的目錄,2。系統(tǒng)目錄4.windowssystem32,3。16位系統(tǒng)目錄,4。windows目錄,和5。當(dāng)前進程目錄。6.環(huán)境變量PATH中的目錄。
當(dāng)值為0時,搜索順序為:1??蓤?zhí)行文件所在的目錄,2。當(dāng)前進程目錄。3.系統(tǒng)目錄窗口系統(tǒng)32,4。16位系統(tǒng)目錄,5.windows目錄,6。環(huán)境變量PATH中的目錄。
4 DLL的加載與連接Windows DLL加載(ntdll.dll除外)和連接是通過ntdll.dll的一個函數(shù)LdrInitializeThunk實現(xiàn)的。首先解釋函數(shù)名LdrInitializeThunk()?!癓dr”顯然是“Loader”的縮寫。而“Thunk”的意思是“翻譯”、“轉(zhuǎn)換”,或者是起到“橋梁”作用的東西。這個詞在一般字典里是找不到的,但在微軟資料和文檔中卻是常用詞。這個術(shù)語起源于編譯技術(shù),意思是一小段旨在獲取地址的代碼。它最初用于函數(shù)調(diào)用中“形式參數(shù)”和“實際參數(shù)”的組合。后來這個術(shù)語有了很多新的特殊含義和用途,但是DLL的動態(tài)連接本質(zhì)上類似于調(diào)用函數(shù)時的“形式與現(xiàn)實的結(jié)合”。
一個DLL文件包含一個導(dǎo)出函數(shù)表。這些派生函數(shù)通過它們的符號名和稱為標(biāo)識號的整數(shù)與外界聯(lián)系在一起。函數(shù)表還包含DLL中函數(shù)的地址。當(dāng)應(yīng)用程序加載一個DLL模塊時,它不知道調(diào)用函數(shù)的實際地址,但它知道函數(shù)的符號名和標(biāo)識號。動態(tài)鏈接過程在加載DLL模塊時動態(tài)建立函數(shù)調(diào)用和函數(shù)地址的對應(yīng)關(guān)系表。如果重新編譯并重建DLL文件,除非更改導(dǎo)出函數(shù)的符號名和參數(shù)序列,否則不需要修改應(yīng)用程序。
5 DLL注冊及為什么需要注冊?許多系統(tǒng)故障是由丟失、損壞或未注冊的動態(tài)鏈接庫文件引起的。例如,如果Windows XP的壓縮文件夾功能失敗,很可能是系統(tǒng)目錄中的fldr.dll沒有注冊。對此類故障的大多數(shù)解決方案是下載相應(yīng)的動態(tài)鏈接庫并運行以下命令:
%1在(%windir%system32*。regsvr32.exe/s % 1
很多人不明白為什么。是不是所有的dll都可以做到這一點?
其實系統(tǒng)里有兩種dll,一種不用注冊就可以用,一種注冊后才能用。就像員工名單上記錄的臨時工和長期合同工的區(qū)別一樣。怎么才能區(qū)分這兩個dll?方法很簡單。可以用一個工具(比如Dependency Walker)打開這個DLL,看看函數(shù)輸出表。如果它包含以下兩個函數(shù)(前者是注冊的DLL,后者是未注冊的DLL),那么它必須是需要注冊的DLL才能使用。
DllRegisterServerDllUnregisterServerregsvr32命令實際上是在DLL中調(diào)用這兩個函數(shù)(“regsvr32 /u DLL文件名”調(diào)用DllUnregisterServer unregister函數(shù))。
注冊和不注冊,。dll文件位于system32下。不同的是,如果注冊的話,注冊表中會有相應(yīng)的信息,同時會加載到dll緩存中。如果沒有注冊信息和緩存,就無法使用(操作系統(tǒng)的一些核心功能會在你啟動的時候加載到內(nèi)存中,在后臺開始運行,所以程序、數(shù)據(jù)、模塊都需要進入內(nèi)存才能訪問。)。
文件注冊前后沒有變化,只有相應(yīng)的信息通過命令添加到注冊表中。
注冊文件的命令行是regsrv32
regsrv 32 xxx.dll
reg SRV 32 xxx.dll/u
regsvr 32[/u][/s][/n][/I[:cmd line]]dllname
參數(shù)描述:
/u-注銷服務(wù)器
/s-無聲;不顯示消息框
/I-調(diào)用DllInstall并向其傳遞可選的[cmd line];與/u一起使用時卸載dll。
/n-不要調(diào)用DllRegisterServer;此選項必須與/i一起使用。
-結(jié)束-
1.《dll文件 Windows DLL基本原理及為何需要注冊》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《dll文件 Windows DLL基本原理及為何需要注冊》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/junshi/1222454.html