綠色資源網(wǎng):您身邊最放心的安全下載站! 最新軟件|熱門排行|軟件分類|軟件專題|論壇轉(zhuǎn)帖|廠商大全

綠色資源網(wǎng)

技術(shù)教程
您的位置:首頁操作系統(tǒng)windows → dll文件介紹

dll文件介紹

我要評論 2011/01/14 19:32:44 來源:綠色資源網(wǎng) 編輯:綠色資源站 [ ] 評論:0 點擊:230次

比較大的應(yīng)用程序都由很多模塊組成,這些模塊分別完成相對獨立的功能,它們彼此協(xié)作來完成整個軟件系統(tǒng)的工作。可能存在一些模塊的功能較為通用,在構(gòu)造其它軟件系統(tǒng)時仍會被使用。在構(gòu)造軟件系統(tǒng)時,如果將所有模塊的源代碼都靜態(tài)編譯到整個應(yīng)用程序 EXE 文件中,會產(chǎn)生一些問題:一個缺點是增加了應(yīng)用程序的大小,它會占用更多的磁盤空間,程序運行時也會消耗較大的內(nèi)存空間,造成系統(tǒng)資源的浪費;另一個缺點是,在編寫大的 EXE 程序時,在每次修改重建時都必須調(diào)整編譯所有源代碼,增加了編譯過程的復(fù)雜性,也不利于階段性的單元測試。

Windows 系統(tǒng)平臺上提供了一種完全不同的較有效的編程和運行環(huán)境,你可以將獨立的程序模塊創(chuàng)建為較小的 DLL (Dynamic Linkable Library) 文件,并可對它們單獨編譯和測試。在運行時,只有當(dāng) EXE 程序確實要調(diào)用這些 DLL 模塊的情況下,系統(tǒng)才會將它們裝載到內(nèi)存空間中。這種方式不僅減少了 EXE 文件的大小和對內(nèi)存空間的需求,而且使這些 DLL 模塊可以同時被多個應(yīng)用程序使用。Windows 自己就將一些主要的系統(tǒng)功能以 DLL 模塊的形式實現(xiàn)。

一般來說,DLL 是一種磁盤文件,以.dll、.DRV、.FON、.SYS 和許多以 .EXE 為擴展名的系統(tǒng)文件都可以是 DLL。它由全局?jǐn)?shù)據(jù)、服務(wù)函數(shù)和資源組成,在運行時被系統(tǒng)加載到調(diào)用進程的虛擬空間中,成為調(diào)用進程的一部分。如果與其它 DLL 之間沒有沖突,該文件通常映射到進程虛擬空間的同一地址上。DLL 模塊中包含各種導(dǎo)出函數(shù),用于向外界提供服務(wù)。DLL 可以有自己的數(shù)據(jù)段,但沒有自己的堆棧,使用與調(diào)用它的應(yīng)用程序相同的堆棧模式;一個 DLL 在內(nèi)存中只有一個實例;DLL 實現(xiàn)了代碼封裝性;DLL 的編制與具體的編程語言及編譯器無關(guān)。

在 Win32 環(huán)境中,每個進程都復(fù)制了自己的讀/寫全局變量。如果想要與其它進程共享內(nèi)存,必須使用內(nèi)存映射文件或者聲明一個共享數(shù)據(jù)段。DLL 模塊需要的堆棧內(nèi)存都是從運行進程的堆棧中分配出來的。Windows 在加載 DLL 模塊時將進程函數(shù)調(diào)用與 DLL 文件的導(dǎo)出函數(shù)相匹配。Windows 操作系統(tǒng)對 DLL 的操作僅僅是把 DLL 映射到需要它的進程的虛擬地址空間里去。DLL 函數(shù)中的代碼所創(chuàng)建的任何對象(包括變量)都歸調(diào)用它的線程或進程所有。

調(diào)用方式

1、靜態(tài)調(diào)用方式:由編譯系統(tǒng)完成對 DLL 的加載和應(yīng)用程序結(jié)束時 DLL 卸載的編碼(如還有其它程序使用該 DLL,則 Windows 對 DLL 的應(yīng)用記錄減1,直到所有相關(guān)程序都結(jié)束對該 DLL 的使用時才釋放它,簡單實用,但不夠靈活,只能滿足一般要求。

隱式的調(diào)用:需要把產(chǎn)生動態(tài)連接庫時產(chǎn)生的 .LIB 文件加入到應(yīng)用程序的工程中,想使用 DLL 中的函數(shù)時,只須說明一下。隱式調(diào)用不需要調(diào)用 LoadLibrary() 和 FreeLibrary()。程序員在建立一個 DLL 文件時,鏈接程序會自動生成一個與之對應(yīng)的 LIB 導(dǎo)入文件。該文件包含了每一個 DLL 導(dǎo)出函數(shù)的符號名和可選的標(biāo)識號,但是并不含有實際的代碼。LIB 文件作為 DLL 的替代文件被編譯到應(yīng)用程序項目中。

當(dāng)程序員通過靜態(tài)鏈接方式編譯生成應(yīng)用程序時,應(yīng)用程序中的調(diào)用函數(shù)與 LIB 文件中導(dǎo)出符號相匹配,這些符號或標(biāo)識號進入到生成的 EXE 文件中。LIB 文件中也包含了對應(yīng)的 DL L文件名(但不是完全的路徑名),鏈接程序?qū)⑵浯鎯υ?EXE 文件內(nèi)部。

當(dāng)應(yīng)用程序運行過程中需要加載 DLL 文件時,Windows 根據(jù)這些信息發(fā)現(xiàn)并加載 DLL,然后通過符號名或標(biāo)識號實現(xiàn)對 DLL 函數(shù)的動態(tài)鏈接。所有被應(yīng)用程序調(diào)用的 DLL 文件都會在應(yīng)用程序 EXE 文件加載時被加載在到內(nèi)存中??蓤?zhí)行程序鏈接到一個包含 DLL 輸出函數(shù)信息的輸入庫文件(.LIB文件)。操作系統(tǒng)在加載使用可執(zhí)行程序時加載 DLL。可執(zhí)行程序直接通過函數(shù)名調(diào)用 DLL 的輸出函數(shù),調(diào)用方法和程序內(nèi)部其 它的函數(shù)是一樣的。

2、動態(tài)調(diào)用方式:是由編程者用 API 函數(shù)加載和卸載 DLL 來達到調(diào)用 DLL 的目的,使用上較復(fù)雜,但能更加有效地使用內(nèi)存,是編制大型應(yīng)用程序時的重要方式。

顯式的調(diào)用:是指在應(yīng)用程序中用 LoadLibrary 或 MFC 提供的 AfxLoadLibrary 顯式的將自己所做的動態(tài)連接庫調(diào)進來,動態(tài)連接庫的文件名即是上面兩個函數(shù)的參數(shù),再用 GetProcAddress() 獲取想要引入的函數(shù)。自此,你就可以象使用如同本應(yīng)用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在應(yīng)用程序退出之前,應(yīng)該用 FreeLibrary 或 MFC 提供的 AfxFreeLibrary 釋放動態(tài)連接庫。直接調(diào)用 Win32 的 LoadLibary 函數(shù),并指定 DLL 的路徑作為參數(shù)。LoadLibary 返回 HINSTANCE 參數(shù),應(yīng)用程序在調(diào)用 GetProcAddress 函數(shù)時使用這一參數(shù)。GetProcAddress 函數(shù)將符號名或標(biāo)識號轉(zhuǎn)換為 DLL 內(nèi)部的地址。程序員可以決定 DLL 文件何時加載或不加載,顯式鏈接在運行時決定加載哪個 DLL 文件。使用 DLL 的程序在使用之前必須加載(LoadLibrary)加載DLL從而得到一個DLL模塊的句柄,然后調(diào)用 GetProcAddress 函數(shù)得到輸出函數(shù)的指針,在退出之前必須卸載DLL(FreeLibrary)。

Windows將遵循下面的搜索順序來定位 DLL:

  1. 包含EXE文件的目錄
  2. 進程的當(dāng)前工作目錄
  3. Windows系統(tǒng)目錄
  4. Windows目錄
  5. 列在 Path 環(huán)境變量中的一系列目錄

MFC中的DLL

  • Non-MFC DLL:指的是不用 MFC 的類庫結(jié)構(gòu),直接用 C 語言寫的 DLL,其輸出的函數(shù)一般用的是標(biāo)準(zhǔn) C 接口,并能被 非 MFC 或 MFC 編寫的應(yīng)用程序所調(diào)用。
  • Regular DLL:和下述的 Extension DLLs 一樣,是用 MFC 類庫編寫的。明顯的特點是在源文件里有一個繼承 CWinApp 的類。其又可細分成靜態(tài)連接到 MFC 和動態(tài)連接到 MFC 上的。

    靜態(tài)連接到 MFC 的動態(tài)連接庫只被 VC 的專業(yè) 版和企業(yè)版所支持。該類 DLL 應(yīng)用程序里頭的輸出函數(shù)可以被任意 Win32 程序使用,包括使用 MFC 的應(yīng)用程序。輸入函數(shù)有如下形式:

    extern "C" EXPORT YourExportedFunction();

    如果沒有 extern "C" 修飾,輸出函數(shù)僅僅能從 C++ 代碼中調(diào)用。

    DLL 應(yīng)用程序從 CWinApp 派生,但沒有消息循環(huán)。

    動態(tài)鏈接到 MFC 的 規(guī)則 DLL 應(yīng)用程序里頭的輸出函數(shù)可以被任意 Win32 程序使用,包括使用 MFC 的應(yīng)用程序。但是,所有從 DLL 輸出的函數(shù)應(yīng)該以如下語句開始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

    此語句用來正確地切換 MFC 模塊狀態(tài)。

    Regular DLL能夠被所有支持 DLL 技術(shù)的語言所編寫的應(yīng)用程序所調(diào)用。在這種動態(tài)連接庫中,它必須有一個從 CWinApp 繼承下來的類,DLLMain 函數(shù)被 MFC 所提供,不用自己顯式的寫出來。

  • Extension DLL:用來實現(xiàn)從 MFC 所繼承下來的類的重新利用,也就是說,用這種類型的動態(tài)連接庫,可以用來輸出一個從 MFC 所繼承下來的類。它輸出的函數(shù)僅可以被使用 MFC 且動態(tài)鏈接到 MFC 的應(yīng)用程序使用??梢詮?MFC 繼承你所想要的、更適于你自己用的類,并把它提供給你的應(yīng)用程序。你也可隨意的給你的應(yīng)用程序提供 MFC 或 MFC 繼承類的對象指針。Extension DLL使用 MFC 的動態(tài)連接版本所創(chuàng)建的,并且它只被用 MFC 類庫所編寫的應(yīng)用程序所調(diào)用。Extension DLLs 和 Regular DLLs 不一樣,它沒有從 CWinApp 繼承而來的類的對象,所以,你必須為自己 DLLMain 函數(shù)添加初始化代碼和結(jié)束代碼。

    和規(guī)則 DLL 相比,有以下不同:

    1、它沒有從 CWinApp 派生的對象;

    2、它必須有一個 DLLMain 函數(shù);

    3、DLLMain 調(diào)用 AfxInitExtensionModule 函數(shù),必須檢查該函數(shù)的返回值,如果返回0,DLLMmain 也返回 0;

  • 4、如果它希望輸出 CRuntimeClass 類型的對象或者資源,則需要提供一個初始化函數(shù)來創(chuàng)建一個 CDynLinkLibrary 對象。并且,有必要把初始化函數(shù)輸出;

    5、使用擴展 DLL 的 MFC 應(yīng)用程序必須有一個從 CWinApp 派生的類,而且,一般在InitInstance 里調(diào)用擴展 DLL 的初始化函數(shù)。

    DLL入口函數(shù)

    1、每一個 DLL 必須有一個入口點,DLLMain 是一個缺省的入口函數(shù)。DLLMain 負(fù)責(zé)初始化和結(jié)束工作,每當(dāng)一個新的進程或者該進程的新的線程訪問 DLL 時,或者訪問 DLL 的每一個進程或者線程不再使用DLL或者結(jié)束時,都會調(diào)用 DLLMain。但是,使用 TerminateProcess 或 TerminateThread 結(jié)束進程或者線程,不會調(diào)用 DLLMain。

    DLLMain的函數(shù)原型:

    BOOL APIENTRY DLLMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID
    lpReserved)
    {
      switch(ul_reason_for_call)
      {
      case DLL_PROCESS_ATTACH:
      .......
      case DLL_THREAD_ATTACH:
      .......
      case DLL_THREAD_DETACH:
      .......
      case DLL_PROCESS_DETACH:
      .......
      return TRUE;
      }
    }

    參數(shù):

    hMoudle:是動態(tài)庫被調(diào)用時所傳遞來的一個指向自己的句柄(實際上,它是指向_DGROUP段的一個選擇符);

    ul_reason_for_call:是一個說明動態(tài)庫被調(diào)原因的標(biāo)志。當(dāng)進程或線程裝入或卸載動態(tài)連接庫的時

關(guān)鍵詞:dll,dll文件

閱讀本文后您有什么感想? 已有 人給出評價!

  • 0 歡迎喜歡
  • 0 白癡
  • 0 拜托
  • 0 哇
  • 0 加油
  • 0 鄙視