久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

DLL

來自站長百科
跳轉(zhuǎn)至: 導(dǎo)航、? 搜索

動態(tài)鏈接庫(Dynamic Link Library或者Dynamic-link library,縮寫為DLL),又稱為動態(tài)連結(jié)庫,是微軟公司在微軟視窗操作系統(tǒng)中實現(xiàn)共享函數(shù)庫概念的一種實作方式。這些庫函數(shù)的擴(kuò)展名是.DLL、.OCX(包含ActiveX控制的庫)或者.DRV(舊式的系統(tǒng)驅(qū)動程序)。

所謂動態(tài)鏈接,就是把一些經(jīng)常會共用的代碼(靜態(tài)鏈接的OBJ程序庫)制作成DLL檔,當(dāng)可執(zhí)行文件調(diào)用到DLL檔內(nèi)的函數(shù)時,Windows操作系統(tǒng)才會把DLL檔加載存儲器內(nèi),DLL檔本身的結(jié)構(gòu)就是可可執(zhí)行文件,當(dāng)程序需求函數(shù)才進(jìn)行鏈接。通過動態(tài)鏈接方式,存儲器浪費(fèi)的情形將可大幅降低。

DLL的文檔格式與視窗EXE文檔一樣——也就是說,等同于32位視窗的可移植執(zhí)行文檔(PE)和16位視窗的New Executable(NE)。作為EXE格式,DLL可以包括源代碼、數(shù)據(jù)和資源的多種組合。

在更廣泛的意義上說,任何同樣文檔格式的電腦文件都可以稱作資源DLL。這樣的DLL的例子有有擴(kuò)展名ICL為的圖標(biāo)庫、擴(kuò)展名為FON和FOT的字體文檔。

背景[ ]

DLL的最初目的是節(jié)約應(yīng)用程序所需的磁盤和內(nèi)存空間。在一個傳統(tǒng)的非共享庫中,一部分代碼簡單地附加到調(diào)用的程序上。如果兩個程序調(diào)用同一個子程序,就會出現(xiàn)兩份那段代碼。相反,許多應(yīng)用共享的代碼能夠切分到一個DLL中,在硬盤上存為一個文檔,在內(nèi)存中使用一個實例(instance)。DLL的廣泛應(yīng)用使得早期的視窗能夠運(yùn)行在緊巴巴的內(nèi)存條件下。

DLL提供了如模塊化這樣的共享庫的普通好處。模塊化允許僅僅更改幾個應(yīng)用程序共享使用的一個DLL中的代碼和數(shù)據(jù)而不需要更改應(yīng)用程序自身。這種模塊化的基本形式允許如Microsoft Office、Microsoft Visual Studio、甚至微軟視窗自身這樣大的應(yīng)用程序使用較為緊湊的補(bǔ)丁和服務(wù)包。

模塊化的另外一個好處是插件的通用接口使用。單個的接口允許舊的模塊與新的模塊一樣能夠與以前的應(yīng)用程序運(yùn)行時無縫地集成到一起,而不需要對應(yīng)用程序本身作任何更改。這種動態(tài)擴(kuò)展的思想在ActiveX中發(fā)揮到了極致。

盡管有這么多的優(yōu)點(diǎn),使用DLL也有一個缺點(diǎn):DLL地獄,也就是幾個應(yīng)用程序在使用同一個共享DLL庫發(fā)生版本沖突。這樣的沖突可以通過將不同版本的問題DLL放到應(yīng)用程序所在的文件夾而不是放到系統(tǒng)文件夾來解決;但是,這樣將抵消共享DLL節(jié)約的空間。目前,Microsoft .NET將解決DLL hell問題當(dāng)作自己的目標(biāo),它允許同一個共享庫的不同版本并列共存。由于現(xiàn)代的計算機(jī)有足夠的磁盤空間和內(nèi)存,這也可以作為一個合理的實現(xiàn)方法。

特征

內(nèi)存管理[ ]

在Win32中,DLL文檔按照片段(sections)進(jìn)行組織。每個片段有它自己的屬性,如可寫或是只讀、可執(zhí)行(代碼)或者不可執(zhí)行(數(shù)據(jù))等等。

DLL代碼段通常被使用這個DLL的進(jìn)程所共享;也就是說它們在物理內(nèi)存中占據(jù)一個地方,并且不會出現(xiàn)在頁面文檔中。如果代碼段所占據(jù)的物理內(nèi)存被收回,它的內(nèi)容就會被放棄,后面如果需要的話就直接從DLL文檔重新加載。

與代碼段不同,DLL的數(shù)據(jù)段通常是私有的;也就是說,每個使用DLL的進(jìn)程都有自己的DLL數(shù)據(jù)副本。作為選擇,數(shù)據(jù)段可以設(shè)置為共享,允許通過這個共享內(nèi)存區(qū)域進(jìn)行進(jìn)程間通信。但是,因為用戶權(quán)限不能應(yīng)用到這個共享DLL內(nèi)存,這將產(chǎn)生一個安全漏洞;也就是一個進(jìn)程能夠破壞共享數(shù)據(jù),這將導(dǎo)致其它的共享進(jìn)程異常。例如,一個使用訪客賬號的進(jìn)程將可能通過這種方式破壞其它運(yùn)行在特權(quán)賬號的進(jìn)程。這是在DLL中避免使用共享片段的一個重要原因。

當(dāng)DLL被如UPX這樣一個可執(zhí)行的packer壓縮時,它的所有代碼段都標(biāo)記為可以讀寫并且是非共享的??梢宰x寫的代碼段,類似于私有數(shù)據(jù)段,是每個進(jìn)程私有的并且被頁面文檔備份。這樣,壓縮DLL將同時增加內(nèi)存和磁盤空間消耗,所以共享DLL應(yīng)當(dāng)避免使用壓縮DLL。

符號解析和綁定[ ]

DLL輸出的每個函數(shù)都由一個數(shù)字序號唯一標(biāo)識,也可以由可選的名字標(biāo)識。同樣,DLL引入的函數(shù)也可以由序號或者名字標(biāo)識。對于內(nèi)部函數(shù)來說,只輸出序號的情形很常見。對于大多數(shù)視窗API函數(shù)來說名字是不同視窗版本之間保留不變的;序號有可能會發(fā)生變化。這樣,我們不能根據(jù)序號引用視窗API函數(shù)。

按照序號引用函數(shù)并不一定比按照名字引用函數(shù)性能更好:DLL輸出表是按照名字排列的,所以對半查找可以用來在在這個表中根據(jù)名字查找這個函數(shù)。另外一方面,只有線性查找才可以用于根據(jù)序號查找函數(shù)。

將一個可執(zhí)行文件綁定到一個特定版本的DLL也是可能的,這也就是說,可以在編譯時解析輸入函數(shù)(imported functions)的地址。對于綁定的輸入函數(shù),連結(jié)工具保存了輸入函數(shù)綁定的DLL的時間戳和校驗和。在運(yùn)行時Windows檢查是否正在使用同樣版本的庫,如果是的話,Windows將繞過處理輸入函數(shù);否則如果庫與綁定的庫不同,Windows將按照正常的方式處理輸入函數(shù)。

綁定的可執(zhí)行文件如果運(yùn)行在與它們編譯所用的環(huán)境一樣,函數(shù)調(diào)用將會較快,如果是在一個不同的環(huán)境它們就等同于正常的調(diào)用,所以綁定輸入函數(shù)沒有任何的缺點(diǎn)。例如,所有的標(biāo)準(zhǔn)Windows應(yīng)用程序都綁定到它們各自的Windows發(fā)布版本的系統(tǒng)DLL。將一個應(yīng)用程序輸入函數(shù)綁定到它的目的環(huán)境的好機(jī)會是在應(yīng)用程序安裝的過程。

運(yùn)行時顯式鏈接[ ]

對每個DLL來說,Windows存儲了一個全局計數(shù)器,每多一個進(jìn)程使用便多額外一個。LoadLibrary與FreeLibrary指令影響每一個進(jìn)程內(nèi)含的計數(shù)器;動態(tài)連結(jié)則不影響。因此借由調(diào)用FreeLibrary多次,從存儲器反加載一DLL是很重要的。一個進(jìn)程可以從它自己的VAS注銷此計數(shù)器。 D LL文檔能夠在運(yùn)行時使用LoadLibrary(或者LoadLibraryEx)API函數(shù)進(jìn)行顯式調(diào)用,這個的過程微軟簡單地稱為運(yùn)行時動態(tài)調(diào)用。API函數(shù)GetProcAddress根據(jù)查找輸出名稱符號、FreeLibrary卸載DLL。這些函數(shù)類似于POSIX標(biāo)準(zhǔn)API中的dlopen、dlsym、和dlclose。

注意微軟簡單稱為運(yùn)行時動態(tài)鏈接的運(yùn)行時隱式鏈接,如果不能找到鏈接的DLL文檔,Windows將提示一個錯誤消息并且調(diào)用應(yīng)用程序失敗。應(yīng)用程序開發(fā)人員不能通過編譯鏈接來處理這種缺少DLL文檔的隱式鏈接問題。另外一方面,對于顯式鏈接,開發(fā)人員有機(jī)會提供一個完善的出錯處理機(jī)制。

運(yùn)行時顯式鏈接的過程在所有語言中都是相同的,因為它依賴于Windows API而不是語言結(jié)構(gòu)。

導(dǎo)出DLL函數(shù)[ ]

要導(dǎo)出 DLL 函數(shù),您可以向?qū)С龅?DLL 函數(shù)中添加函數(shù)關(guān)鍵字,也可以創(chuàng)建模塊定義文件 (.def) 以列出導(dǎo)出的 DLL 函數(shù)。兩種方法

方法一、向?qū)С龅?DLL 函數(shù)中添加函數(shù)關(guān)鍵字

要使用函數(shù)關(guān)鍵字,您必須使用以下關(guān)鍵字來聲明要導(dǎo)出的各個函數(shù):

__declspec(dllexport)

要在應(yīng)用程序中使用導(dǎo)出的 DLL 函數(shù),您必須使用以下關(guān)鍵字來聲明要導(dǎo)入的各個函數(shù):

__declspec(dllimport)

通常情況下,您最好使用一個包含 define 語句和 ifdef 語句的頭文件,以便分隔導(dǎo)出語句和導(dǎo)入語句。

方法二、創(chuàng)建模塊定義文件 (.def) 以列出導(dǎo)出的 DLL 函數(shù)

使用模塊定義文件來聲明導(dǎo)出的 DLL 函數(shù)。當(dāng)您使用模塊定義文件時,您不必向?qū)С龅?DLL 函數(shù)中添加函數(shù)關(guān)鍵字。在模塊定義文件中,您可以聲明 DLL 的 LIBRARY 語句和 EXPORTS 語句。

特別調(diào)用[ ]

關(guān)于特定情況下的調(diào)用,比如DLL函數(shù)中使用到了win32 API或者將C++生成的DLL供標(biāo)準(zhǔn)C語言使用,則需要注意以下一些情況:

如果使用到了win32 API,則應(yīng)該使用調(diào)用方式為“__stdcall”。

在將C++生成的DLL供標(biāo)準(zhǔn)C語言使用,輸出文件需要用“extern "C"”修飾,否則不能被標(biāo)準(zhǔn)C語言調(diào)用。如果使用“__stdcall”調(diào)用方式,可能產(chǎn)生C不識別的修飾名,所以設(shè)置導(dǎo)出函數(shù)時要采用.def文件形式,而不是__declspec(dllexport)形式。后者會進(jìn)行修飾名轉(zhuǎn)換,C語言無法識別函數(shù)。

下面的代碼是一個定義文件的示例。   // SampleDLL.def   //   LIBRARY "sampleDLL"   EXPORTS HelloWorld示例 DLL 和應(yīng)用程序XXXXXXXX 在 Microsoft Visual C++ 6.0 中,可以通過選擇“Win32 動態(tài)鏈接庫”項目類型或“MFC 應(yīng)用程序向?qū)?(dll)”來創(chuàng)建 DLL。下面的代碼是一個在 Visual C++ 中通過使用“Win32 動態(tài)鏈接庫”項目類型創(chuàng)建的 DLL 的示例。

// SampleDLL.cpp
  //#include "stdafx.h"
  #define EXPORTING_DLL
  #include "sampleDLL.h"
  BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
  {
  return TRUE;
  }
  void HelloWorld(){
  MessageBox( NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
  }
  // File: SampleDLL.h
  //#ifndef INDLL_H
  #define INDLL_H
  #ifdef EXPORTING_DLLextern __declspec(dllexport) void HelloWorld() ;
  #elseextern __declspec(dllimport) void HelloWorld() ;
  #endif
  #endif

下面的代碼是一個“Win32 應(yīng)用程序”項目的示例,該示例調(diào)用 SampleDLL DLL 中的導(dǎo)出 DLL 函數(shù)。

// SampleApp.cpp
  //#include "stdafx.h"
  #include "sampleDLL.h"
  int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  {
  HelloWorld();
  return 0;
  }

注意:在加載時動態(tài)鏈接中,您必須鏈接在生成 SampleDLL 項目時創(chuàng)建的 SampleDLL.lib 導(dǎo)入庫。

DLL內(nèi)容說明[ ]

  • KERNEL32.DLL ---- 低級內(nèi)核函數(shù)。使用他可以完成內(nèi)存管理、任務(wù)管理、資源控制等。
  • USER32.DLL------于windows管理有關(guān)的函數(shù)。消息、菜單、光標(biāo)、計時器、通信和其他大多數(shù)非現(xiàn)實函數(shù)都可以從這里找到
  • GDI32.DLL-------圖形設(shè)備接口庫。于設(shè)備輸出有關(guān)的函數(shù):大多數(shù)繪圖、顯示場景、圖元文件、坐標(biāo)及其字體函數(shù)都可以從這里找到。
  • COMDLG32.DLL\LZ32.DLL\VERSION.DLL\---這都是提供一些附加函數(shù)的庫,包括通用對話框、文件壓縮、版本控制的支持。
  • COMCTL32.DLL --------一個新的windows控件集合,比如TreeView和RichTextBox等等,最初這個是為了win95而制作的,但是現(xiàn)在也使用與NT下
  • MAPI32.DLL---------提供了一套電子郵件的專用函數(shù)
  • NETAPI32.DLL--------提供了一套訪問和控制網(wǎng)絡(luò)的函數(shù)
  • ODBC32.DLL--------ODBC功能的DLL之一
  • WINMM.DLL--------是多媒體控制訪問函數(shù)集合
  • DLL(Delay Locked Loop,延時鎖定回路提供一個數(shù)據(jù)濾波信號)

相關(guān)條目[ ]

參考來源[ ]