�(dòng)�(tài)鏈接庫是一�(gè)可以�(zhí)行的并可以被多�(gè)Windows�(yīng)用程序共享的程序模塊,模塊中包含了一些可以被多�(gè)Windows�(yīng)用程序或DLL共享的代�、數(shù)�(jù)和資��
所謂動(dòng)�(tài)鏈接,就是把一些經(jīng)常會共用的代碼(靜態(tài)鏈接的OBJ程序庫)制作成DLL�,當(dāng)可執(zhí)行文件調(diào)用到DLL檔內(nèi)的函�(shù)�(shí),windows操作系統(tǒng)才會把DLL檔加載存儲器�(nèi),DLL檔本身的�(jié)�(gòu)就是可可�(zhí)行文�,當(dāng)程序需求函�(shù)才�(jìn)行鏈�。通過�(dòng)�(tài)鏈接方式,存儲器浪費(fèi)的情形將可大幅降��
�(dòng)�(tài)鏈接庫的最初目的是節(jié)約應(yīng)用程序所需的磁盤和�(nèi)存空�。在一�(gè)傳統(tǒng)的非共享庫中,一部分代碼簡單地附加到�(diào)用的程序�。如果兩�(gè)程序�(diào)用同一�(gè)子程�,就會出�(xiàn)兩份那段代碼。相�,許多應(yīng)用共享的代碼能夠切分到一�(gè)�(dòng)�(tài)鏈接庫中,在硬盤上存為一�(gè)文檔,在�(nèi)存中使用一�(gè)�(shí)例(instance�。動(dòng)�(tài)鏈接庫的廣泛�(yīng)用使得早期的視窗能夠�(yùn)行在緊巴巴的�(nèi)存條件下�
�(dòng)�(tài)鏈接庫提供了如模塊化這樣的共享庫的普通好�。模塊化允許僅僅更改幾�(gè)�(yīng)用程序共享使用的一�(gè)�(dòng)�(tài)鏈接庫中的代碼和�(shù)�(jù)而不需要更改應(yīng)用程序自�。這種模塊化的基本形式允許如Microsoft Office、Microsoft Visual Studio、甚至微軟視窗自身這樣大的�(yīng)用程序使用較為緊湊的�(bǔ)丁和服務(wù)��
模塊化的另外一�(gè)好處是插件的通用接口使用。單�(gè)的接口允許舊的模塊與新的模塊一樣能夠與以前的應(yīng)用程序運(yùn)行時(shí)無縫地集成到一起,而不需要對�(yīng)用程序本身作任何更改。這種�(dòng)�(tài)�(kuò)展的思想在ActiveX中發(fā)揮到��
盡管有這么多的�(yōu)�(diǎn),使用動(dòng)�(tài)鏈接庫也有一�(gè)缺點(diǎn):動(dòng)�(tài)鏈接庫地�,也就是幾�(gè)�(yīng)用程序在使用同一�(gè)共享�(dòng)�(tài)鏈接庫庫�(fā)生版本沖�。這樣的沖突可以通過將不同版本的問題�(dòng)�(tài)鏈接庫放到應(yīng)用程序所在的文件夾而不是放到系�(tǒng)文件夾來解決;但�,這樣將抵消共享動(dòng)�(tài)鏈接庫節(jié)約的空間。目前,Microsoft .NET將解決動(dòng)�(tài)鏈接� hell問題�(dāng)作自己的目標(biāo),它允許同一�(gè)共享庫的不同版本并列共存。由于現(xiàn)代的�(jì)算機(jī)有足夠的磁盤空間和內(nèi)�,這也可以作為一�(gè)合理的實(shí)�(xiàn)方法�
�(nèi)存管�
在Win32�,DLL文檔按照片段(sections)�(jìn)行組�。每�(gè)片段有它自己的屬性,如可寫或是只讀、可�(zhí)行(代碼)或者不可執(zhí)行(�(shù)�(jù))等等�
DLL代碼段通常被使用這�(gè)DLL的�(jìn)程所共享;也就是說它們在物理�(nèi)存中占據(jù)一�(gè)地方,并且不會出�(xiàn)在頁面文檔中。如果代碼段所占據(jù)的物理內(nèi)存被收回,它的內(nèi)容就會被放棄,后面如果需要的話就直接從DLL文檔重新加載�
與代碼段不同,DLL的數(shù)�(jù)段通常是私有的;也就是�,每�(gè)使用DLL的�(jìn)程都有自己的DLL�(shù)�(jù)副本。作為選擇,�(shù)�(jù)段可以設(shè)置為共享,允許通過這�(gè)共享�(nèi)存區(qū)域�(jìn)行�(jìn)程間通信。但�,因?yàn)橛脩�?quán)限不能應(yīng)用到這�(gè)共享DLL�(nèi)存,這將�(chǎn)生一�(gè)安全漏洞;也就是一�(gè)�(jìn)程能夠破壞共享數(shù)�(jù),這將�(dǎo)致其它的共享�(jìn)程異常。例�,一�(gè)使用訪客賬號的�(jìn)程將可能通過這種方式破壞其它�(yùn)行在特權(quán)賬號的�(jìn)�。這是在DLL中避免使用共享片段的一�(gè)重要原因�
�(dāng)DLL被如UPX這樣一�(gè)可執(zhí)行的packer壓縮�(shí),它的所有代碼段都標(biāo)記為可以讀寫并且是非共享的。可以讀寫的代碼�,類似于私有�(shù)�(jù)�,是每�(gè)�(jìn)程私有的并且被頁面文檔備份。這樣,壓縮DLL將同�(shí)增加�(nèi)存和磁盤空間消�,所以共享DLL�(yīng)�(dāng)避免使用壓縮DLL�
符號解析和綁�
DLL輸出的每�(gè)函數(shù)都由一�(gè)�(shù)字序號標(biāo)識,也可以由可選的名字標(biāo)�。同樣,DLL引入的函�(shù)也可以由序號或者名字標(biāo)識。對于內(nèi)部函�(shù)來說,只輸出序號的情形很常見。對于大多數(shù)視窗API函數(shù)來說名字是不同視窗版本之間保留不變的;序號有可能會發(fā)生變�。這樣,我們不能根�(jù)序號引用視窗API函數(shù)�
按照序號引用函數(shù)并不一定比按照名字引用函數(shù)性能更好:DLL輸出表是按照名字排列的,所以對半查找可以用來在在這�(gè)表中根據(jù)名字查找這�(gè)函數(shù)。另外一方面,只有線性查找才可以用于根據(jù)序號查找函數(shù)�
將一�(gè)可執(zhí)行文件綁定到一�(gè)特定版本的DLL也是可能�,這也就是�,可以在編譯�(shí)解析輸入函數(shù)(imported functions)的地址。對于綁定的輸入函數(shù),連結(jié)工具保存了輸入函�(shù)綁定的DLL的時(shí)間戳和校�(yàn)�。在�(yùn)行時(shí)Windows檢查是否正在使用同樣版本的庫,如果是的話,Windows將繞過處理輸入函�(shù);否則如果庫與綁定的庫不�,Windows將按照正常的方式處理輸入函數(shù)�
綁定的可�(zhí)行文件如果運(yùn)行在與它們編譯所用的�(huán)境一�,函�(shù)�(diào)用將會較�,如果是在一�(gè)不同的環(huán)境它們就等同于正常的�(diào)�,所以綁定輸入函�(shù)沒有任何的缺�(diǎn)。例�,所有的�(biāo)�(zhǔn)Windows�(yīng)用程序都綁定到它們各自的Windows�(fā)布版本的系統(tǒng)DLL。將一�(gè)�(yīng)用程序輸入函�(shù)綁定到它的目的環(huán)境的好機(jī)會是在應(yīng)用程序安裝的過程�
�(yùn)行時(shí)顯式鏈接
對每�(gè)DLL來說,Windows存儲了一�(gè)全局�(jì)�(shù)�,每多一�(gè)�(jìn)程使用便多額外一�(gè)。LoadLibrary與FreeLibrary指令影響每一�(gè)�(jìn)程內(nèi)含的�(jì)�(shù)�;動(dòng)�(tài)連結(jié)則不影響。因此借由�(diào)用FreeLibrary多次,從存儲器反加載一DLL是很重要�。一�(gè)�(jìn)程可以從它自己的VAS注銷此計(jì)�(shù)��
DLL文檔能夠在運(yùn)行時(shí)使用LoadLibrary(或者LoadLibraryEx)API函數(shù)�(jìn)行顯式調(diào)�,這�(gè)的過程微軟簡單地稱為�(yùn)行時(shí)�(dòng)�(tài)�(diào)用。API函數(shù)GetProcAddress根據(jù)查找輸出名稱符號、FreeLibrary卸載DLL。這些函數(shù)類似于POSIX�(biāo)�(zhǔn)API中的dlopen、dlsym、和dlclose�
注意微軟簡單稱為�(yùn)行時(shí)�(dòng)�(tài)鏈接的運(yùn)行時(shí)隱式鏈接,如果不能找到鏈接的DLL文檔,Windows將提示一�(gè)�(cuò)誤消息并且調(diào)用應(yīng)用程序失敗。應(yīng)用程序開�(fā)人員不能通過編譯鏈接來處理這種缺少DLL文檔的隱式鏈接問�。另外一方面,對于顯式鏈接,開發(fā)人員有機(jī)會提供一�(gè)完善的出�(cuò)處理�(jī)��
�(yùn)行時(shí)顯式鏈接的過程在所有語言中都是相同的,因?yàn)樗蕾囉赪indows API而不是語言�(jié)�(gòu)�
?�?)應(yīng)用范圍廣�
?�?)便于開�(fā)大型軟件�
?�?)便于對系統(tǒng)�(jìn)行升級�
?�?)隱藏細(xì)節(jié)�
?�?)獨(dú)立于編程語言�
維庫電子�,電子知識,一查百��
已收錄詞�168509�(gè)