綠色資(zī)源網:您身邊最放心的(de)安全(quán)下載站! 最新(xīn)軟(ruǎn)件|熱門排行|軟件分類(lèi)|軟件專題|廠商(shāng)大全

綠色資源網

技術教程(chéng)
您的位置:首頁操作係(xì)統windows → dll文件介紹

dll文件介紹

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

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

Windows 係統平台上提供(gòng)了一種完全不同的較(jiào)有效的編(biān)程和運行環(huán)境,你可以將獨(dú)立的(de)程序模塊創建為較小的(de) DLL (Dynamic Linkable Library) 文件,並可(kě)對它們單獨編譯(yì)和(hé)測(cè)試。在運(yùn)行時(shí),隻有當 EXE 程序確實要調用(yòng)這些 DLL 模塊的情(qíng)況下,係統才(cái)會(huì)將它們(men)裝載到內(nèi)存空(kōng)間中。這(zhè)種方式不僅(jǐn)減少(shǎo)了 EXE 文件的大小和對內存(cún)空(kōng)間的需求,而且(qiě)使這些 DLL 模塊可以同(tóng)時被(bèi)多個應(yīng)用程序使用(yòng)。Windows 自己就將(jiāng)一(yī)些(xiē)主要的係統功能以 DLL 模塊的形(xíng)式實現。

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

在 Win32 環境中,每個進程(chéng)都複製了自己的(de)讀/寫全局變量(liàng)。如果(guǒ)想(xiǎng)要與其它進程共享內存,必(bì)須使用內存映射文(wén)件(jiàn)或者聲明一個共享數(shù)據(jù)段。DLL 模塊需要(yào)的(de)堆棧內(nèi)存都是從(cóng)運行進程的堆棧中分配出來的。Windows 在加載(zǎi) DLL 模塊時將(jiāng)進(jìn)程函數(shù)調(diào)用與 DLL 文件(jiàn)的導出函數相匹(pǐ)配。Windows 操作係統對 DLL 的操作僅僅是把 DLL 映射到需要它的進程的虛(xū)擬地(dì)址空間裏去。DLL 函數中的(de)代碼所創建的(de)任何對象(包括變量)都歸調用它的線(xiàn)程(chéng)或進程所有。

調用(yòng)方式

1、靜態(tài)調用方式:由編譯(yì)係(xì)統完成對 DLL 的加載和應用程序結束時 DLL 卸(xiè)載(zǎi)的(de)編碼(mǎ)(如還有(yǒu)其它程序使用該(gāi) DLL,則 Windows 對 DLL 的應用記(jì)錄減1,直到所有相關程序都結(jié)束對(duì)該 DLL 的使用時才(cái)釋放它,簡單實用,但(dàn)不夠(gòu)靈活(huó),隻能滿足(zú)一般要求。

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

當(dāng)程序員通過靜(jìng)態(tài)鏈接方式編譯生成應用程序時,應用(yòng)程(chéng)序中的調用(yòng)函數與 LIB 文件中導出(chū)符號相匹配,這些(xiē)符(fú)號或標識號進入到生成的(de) EXE 文件中(zhōng)。LIB 文(wén)件(jiàn)中也(yě)包含了對應(yīng)的(de) DL L文件名(但不是完(wán)全的路徑名),鏈接(jiē)程序將其(qí)存儲在 EXE 文件內部。

當(dāng)應用程序運行過(guò)程(chéng)中需要加(jiā)載 DLL 文件時,Windows 根據這些信息發現並加載 DLL,然後通過符(fú)號(hào)名(míng)或標識號實現對 DLL 函數的動態鏈接。所有被應用(yòng)程序調用的 DLL 文件都會在應用程序 EXE 文件加載時被加載在到內存中。可執(zhí)行程序鏈接到一個(gè)包含 DLL 輸出函數信息的輸入(rù)庫文件(.LIB文件)。操作係統在加載使用可執(zhí)行程序時加(jiā)載 DLL。可執行程序(xù)直接通過(guò)函(hán)數名調用 DLL 的輸出函數,調用方法和程序內部其 它的函數是一樣的。

2、動態調用方式:是由編程者(zhě)用 API 函數(shù)加載和卸載 DLL 來達到調用 DLL 的目的,使(shǐ)用上(shàng)較複(fù)雜,但能更加有效地使用內存,是編製大型應用程(chéng)序時的(de)重要方式。

顯式的調用(yòng):是指在(zài)應用程序中(zhōng)用(yòng) LoadLibrary 或 MFC 提供的 AfxLoadLibrary 顯式的將(jiāng)自己所做的動(dòng)態(tài)連(lián)接庫(kù)調(diào)進(jìn)來(lái),動態連(lián)接庫的文(wén)件名即是上麵兩個函(hán)數的參數,再用 GetProcAddress() 獲取(qǔ)想(xiǎng)要引入(rù)的(de)函數。自此,你就可以象使用如同本(běn)應(yīng)用程序自定義的函數一樣來調用此引入函數了。在應用程序退出之(zhī)前,應該用(yòng) FreeLibrary 或 MFC 提(tí)供的(de) AfxFreeLibrary 釋(shì)放動態連接(jiē)庫。直接(jiē)調用 Win32 的 LoadLibary 函(hán)數,並(bìng)指定 DLL 的路徑作(zuò)為參數。LoadLibary 返回(huí) HINSTANCE 參數(shù),應用程序在調用 GetProcAddress 函(hán)數時使用這一(yī)參數。GetProcAddress 函數(shù)將符號名或標識號轉換為 DLL 內(nèi)部(bù)的地址。程序員可以決(jué)定 DLL 文(wén)件何時加載或不加(jiā)載,顯式鏈接在運(yùn)行時決定(dìng)加(jiā)載哪個(gè) DLL 文件。使(shǐ)用(yòng) DLL 的程序在使用之前必須加載(LoadLibrary)加載DLL從而得到一個DLL模塊的句柄(bǐng),然後(hòu)調用 GetProcAddress 函數得到輸出函(hán)數的指針,在退出之前必須卸(xiè)載(zǎi)DLL(FreeLibrary)。

Windows將遵(zūn)循下麵的搜索(suǒ)順(shùn)序來定位(wèi) DLL:

  1. 包含EXE文件的目錄(lù)
  2. 進程的當前(qián)工作(zuò)目錄(lù)
  3. Windows係統目錄(lù)
  4. Windows目錄
  5. 列在 Path 環境變量中的一係(xì)列目錄

MFC中的DLL

  • Non-MFC DLL:指的是不用 MFC 的類庫結構,直(zhí)接用(yòng) C 語言寫(xiě)的 DLL,其輸出的函數一般(bān)用的是標準 C 接口(kǒu),並能被 非 MFC 或 MFC 編寫的應用程序所調用。
  • Regular DLL:和(hé)下述的 Extension DLLs 一(yī)樣,是用 MFC 類庫編寫的。明顯的(de)特點是在源文件(jiàn)裏有(yǒu)一(yī)個繼承 CWinApp 的類。其(qí)又可細(xì)分成靜態連接到 MFC 和動態連接到 MFC 上(shàng)的。

    靜態連接到 MFC 的動態連接庫隻被 VC 的專業 版和企業(yè)版所支持。該類 DLL 應用程序裏(lǐ)頭的輸出函(hán)數可以被任意 Win32 程序使用,包括使用 MFC 的(de)應用程序。輸入函數有(yǒu)如下形式(shì):

    extern "C" EXPORT YourExportedFunction();

    如果沒有 extern "C" 修(xiū)飾,輸出函數僅僅能從 C++ 代碼中調用。

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

    動態鏈接到 MFC 的 規則 DLL 應用程序裏頭的(de)輸(shū)出(chū)函數可以(yǐ)被任意(yì) Win32 程序使用,包括使用 MFC 的應用(yòng)程(chéng)序。但是,所(suǒ)有從 DLL 輸出(chū)的函數應該以如(rú)下語句開始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

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

    Regular DLL能夠被所(suǒ)有支(zhī)持 DLL 技(jì)術的語言所編寫的應用程(chéng)序所調(diào)用(yòng)。在這種(zhǒng)動態連接庫中,它必須有(yǒu)一個從(cóng) CWinApp 繼承(chéng)下來(lái)的類,DLLMain 函數被 MFC 所提供,不用自己顯(xiǎn)式(shì)的寫(xiě)出來。

  • Extension DLL:用(yòng)來實(shí)現從 MFC 所繼承下來的類的重新利用(yòng),也(yě)就是說,用這種類型的動態連(lián)接庫,可以用來輸出(chū)一個(gè)從 MFC 所(suǒ)繼承下來的類。它輸出的函數僅(jǐn)可以被使用 MFC 且動態鏈接到 MFC 的(de)應用程序使用。可(kě)以從 MFC 繼承你所想要的、更適於你自(zì)己用的(de)類(lèi),並把(bǎ)它提供(gòng)給(gěi)你的(de)應用(yòng)程序。你也可隨意的給你的應(yīng)用程序提供 MFC 或(huò) MFC 繼承(chéng)類(lèi)的對象(xiàng)指針。Extension DLL使用 MFC 的動態連(lián)接(jiē)版本(běn)所創建的,並且(qiě)它隻被(bèi)用(yòng) MFC 類(lèi)庫所編寫的應用程(chéng)序所(suǒ)調用(yòng)。Extension DLLs 和 Regular DLLs 不一樣,它(tā)沒有從 CWinApp 繼承而來的類的對象,所以,你必須為自己 DLLMain 函數添加初始(shǐ)化代碼和結束代碼。

    和規則 DLL 相比(bǐ),有(yǒu)以下不同:

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

    2、它必須有一個 DLLMain 函數;

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

  • 4、如(rú)果它希望輸出 CRuntimeClass 類型的對象或(huò)者資源,則需要提供一個初始化函數來創(chuàng)建一(yī)個(gè) CDynLinkLibrary 對象。並(bìng)且(qiě),有必要把初始(shǐ)化(huà)函(hán)數輸出;

    5、使用擴展 DLL 的 MFC 應用程(chéng)序必須有一(yī)個(gè)從 CWinApp 派(pài)生的類,而且,一(yī)般在(zài)InitInstance 裏(lǐ)調用擴展 DLL 的(de)初始(shǐ)化函數。

    DLL入口函數

    1、每一個 DLL 必須有一個入(rù)口點,DLLMain 是一個缺省的入口函數。DLLMain 負責初始化和結束(shù)工作,每當(dāng)一個新的(de)進(jìn)程或者(zhě)該進程的新的線(xiàn)程(chéng)訪問 DLL 時,或者訪問 DLL 的每一個進程(chéng)或者線(xiàn)程不再使用(yòng)DLL或者結束時,都會調用 DLLMain。但是(shì),使用(yòng) TerminateProcess 或 TerminateThread 結束進程或者線程(chéng),不(bú)會調(diào)用 DLLMain。

    DLLMain的(de)函數原型:

    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;
      }
    }

    參數:

    hMoudle:是動態庫被(bèi)調用時所傳遞來的一個指向自己的句柄(實(shí)際(jì)上,它是(shì)指向_DGROUP段(duàn)的一個選擇符);

    ul_reason_for_call:是(shì)一(yī)個說明(míng)動(dòng)態庫被調原因(yīn)的標(biāo)誌。當進(jìn)程或(huò)線程裝入(rù)或卸載動態(tài)連接庫的時

關鍵詞:dll,dll文件

閱讀本文後您(nín)有什麽感想? 已有 人(rén)給出評價!

  • 0 歡(huān)迎喜歡
  • 0 白癡
  • 0 拜托
  • 0 哇
  • 0 加油
  • 0 鄙(bǐ)視