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

綠色資(zī)源網

技術教程
您的位置:首頁(yè)操作係統windows → dll文(wén)件(jiàn)介(jiè)紹

dll文件介(jiè)紹(shào)

我要評論 2011/01/14 19:32:44 來源:綠色資源(yuán)網 編輯:綠色資源站 [ 小(xiǎo)] 評論:0 點擊:230次

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

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

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

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

調(diào)用方式

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

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

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

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

2、動態調用方(fāng)式(shì):是由編程者用 API 函數加(jiā)載和卸載(zǎi) DLL 來達到調(diào)用 DLL 的目的,使用上較複(fù)雜,但能更(gèng)加有效地使(shǐ)用內存,是編(biān)製(zhì)大型應用程序時的重要方式。

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

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

  1. 包含EXE文(wén)件的目錄
  2. 進程(chéng)的當前(qián)工作(zuò)目錄
  3. Windows係統目錄
  4. Windows目錄
  5. 列(liè)在 Path 環境(jìng)變(biàn)量中的一係列目錄

MFC中的DLL

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

    靜態(tài)連接到 MFC 的動(dòng)態連接庫隻被 VC 的專(zhuān)業 版和企業版所支持。該類 DLL 應用程序裏頭的輸出函數可以被(bèi)任(rèn)意 Win32 程序(xù)使用,包(bāo)括使用 MFC 的應用程序。輸入函數有如下形式:

    extern "C" EXPORT YourExportedFunction();

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

    DLL 應(yīng)用程(chéng)序從 CWinApp 派生,但沒有消(xiāo)息循(xún)環(huán)。

    動態鏈接到 MFC 的 規則 DLL 應用程序裏頭的輸(shū)出函數可以被任意 Win32 程序(xù)使(shǐ)用,包(bāo)括(kuò)使用 MFC 的應用(yòng)程(chéng)序。但是,所有從 DLL 輸出的函數應該(gāi)以如下語句開(kāi)始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

    此語句用來正確地切換 MFC 模塊狀態。

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

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

    和規則(zé) DLL 相比,有以(yǐ)下不同:

    1、它沒有從(cóng) CWinApp 派生的(de)對象;

    2、它必(bì)須有(yǒu)一個 DLLMain 函數;

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

  • 4、如果它(tā)希望輸出 CRuntimeClass 類(lèi)型(xíng)的(de)對象或者資源,則需(xū)要提供一個初(chū)始化函數(shù)來(lái)創建一個 CDynLinkLibrary 對象。並且,有(yǒu)必要把初(chū)始(shǐ)化(huà)函數(shù)輸(shū)出;

    5、使用擴展 DLL 的 MFC 應用(yòng)程序必須有一個從 CWinApp 派生的類,而且,一般在InitInstance 裏(lǐ)調用擴展 DLL 的初始化函(hán)數。

    DLL入口函數

    1、每一個 DLL 必須有一個入口點,DLLMain 是一(yī)個缺省的入口(kǒu)函(hán)數。DLLMain 負責初(chū)始化和結束(shù)工(gōng)作,每(měi)當一個新的進程或者該進(jìn)程(chéng)的新的線(xiàn)程訪問 DLL 時,或者訪(fǎng)問 DLL 的每(měi)一個進程或者線程不(bú)再(zài)使用DLL或(huò)者結(jié)束時(shí),都(dōu)會(huì)調用 DLLMain。但是,使用 TerminateProcess 或 TerminateThread 結束進程或者線程,不會調用 DLLMain。

    DLLMain的函數原型:

    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:是(shì)動態庫被(bèi)調用時所傳遞來的一個指向自己的句柄(bǐng)(實際上,它(tā)是指向_DGROUP段的一個(gè)選擇符);

    ul_reason_for_call:是一個說明動(dòng)態庫被調原(yuán)因的(de)標誌(zhì)。當進程或線程裝入或(huò)卸載動(dòng)態連接庫(kù)的時

關鍵詞:dll,dll文件(jiàn)

閱讀本文後您有什麽感(gǎn)想? 已(yǐ)有 人給出評價!

  • 0 歡迎喜歡
  • 0 白癡
  • 0 拜(bài)托
  • 0 哇
  • 0 加油(yóu)
  • 0 鄙視