DLL的含義 優勢 可以更為容易地將更新套用於各個模組,而不會影響該程式的其他部分。例如,您可能具有一個工資計算程式,而稅率每年都會更改。當這些更改被隔離到 DLL 中以後,您無需重新生成或安裝整個程式就可以套用更新。
下面說明了 Windows 作業系統中的一些作為 DLL 實現的檔案: ActiveX 控制項 (.ocx) 檔案ActiveX 控制項的一個示例是日曆控制項,它使您可以從日曆中選擇日期。 控制臺 (.cpl) 檔案.cpl 檔案的一個示例是位於控制臺中的項。每個項都是一個專用 DLL。
設備驅動程式 (.drv) 檔案設備
驅動 程式的一個示例是控制列印到印表機的
印表機驅動程式 。
DLL的優點 當程式使用 DLL 時,具有以下的優點: 使用較少的資源,當多個程式使用同一個函式館時,DLL 可以減少在磁碟和物理記憶體中載入的代碼的重複量。這不僅可以大大影響在前台運行的程式,而且可以大大影響其他在 Windows 作業系統上運行的程式。 推廣模組式體系結構DLL 有助於促進模組式程式的開發。這可以幫助您開發要求提供多個語言版本的大型程式或要求具有模組式體系結構的程式。模組式程式的一個示例是具有多個可以在運行時動態載入的模組的計帳程式。 簡化部署和安裝當 DLL 中的函式需要更新或修復時,部署和安裝 DLL 不要求重新建立程式與該 DLL 的連結。此外,如果多個程式使用同一個 DLL,那么多個程式都將從該更新或修復中獲益。當您使用定期更新或修復的第三方 DLL 時,此問題可能會更頻繁地出現。
DLL 依賴項 當某個程式或 DLL 使用其他 DLL 中的 DLL 函式時,就會創建依賴項。因此,該程式就不再是獨立的,並且如果該依賴項被損壞,該程式就可能遇到問題。例如,如果發生下列操作之一,則該程式可能無法運行: 依賴 DLL 升級到新版本。 修復了依賴 DLL。 依賴 DLL 被其早期版本覆蓋。 從計算機中刪除了依賴 DLL。這些操作通常稱為 DLL 衝突。如果沒有強制實現向後兼容性,則該程式可能無法成功運行。
下表說明了為了幫助最大限度地減少依賴性問題而在 Microsoft Windows 2000 和較高版本的 Windows 作業系統中引入的更改: Windows 檔案保護在 Windows 檔案保護中,作業系統禁止未經授權的代理更新或刪除系統 DLL。因此,當程式安裝操作嘗試刪除或更新被定義為系統 DLL 的 DLL 時,Windows 檔案保護將尋找有效的
數字簽名 。 專用 DLL通過專用 DLL 可以使程式避免遭受對共享 DLL 進行的更改。專用 DLL 使用版本特定信息或空 .local 檔案來強制要求程式所使用的 DLL 的版本。要使用專用 DLL,請在程式根資料夾中查找 DLL。然後,對於新程式,請向該 DLL 中添加版本特定信息。對於舊程式,請使用空 .local 檔案。每個方法都告訴作業系統使用位於程式根資料夾中的專用 DLL。
DLL 故障排除工具 可以使用多個工具來幫助您解決 DLL 問題。以下是其中的部分工具。 Dependency WalkerDependency Walker 工具可以遞歸掃描以尋找程式所使用的所有依賴 DLL。當您在 Dependency Walker 中打開程式時,Dependency Walker 會執行下列檢查: Dependency Walker 檢查是否丟失 DLL。 Dependency Walker 檢查是否存在無效的程式檔案或 DLL。 Dependency Walker 檢查導入函式和導出函式是否匹配。 Dependency Walker 檢查是否存在循環依賴性錯誤。 Dependency Walker 檢查是否存在由於針對另一不同作業系統而無效的模組。通過使用 Dependency Walker,您可以記錄程式使用的所有 DLL。這可能有助於避免和更正將來可能發生的 DLL 問題。當您安裝 Microsoft Visual Studio 6.0 時,Dependency Walker 將位於以下目錄中: drive\Program Files\Microsoft Visual Studio\Common\Tools
DLL Universal Problem SolverDLL Universal Problem Solver (DUPS) 工具用於審核、比較、記錄和顯示 DLL 信息。下表說明了組成 DUPS 工具的實用工具: Dlister.exe該實用工具枚舉計算機中的所有 DLL,並且將此信息記錄到一個文本檔案或
資料庫檔案 中。 Dcomp.exe該實用工具比較在兩個文本檔案中列出的 DLL,並產生包含差異的第三個文本檔案。 Dtxt2DB.exe該實用工具將通過使用 Dlister.exe 實用工具和 Dcomp.exe 實用工具創建的文本檔案載入到 dllHell 資料庫中。 DlgDtxt2DB.exe該實用工具提供 Dtxt2DB.exe 實用工具的
圖形用戶界面 (GUI) 版本。
DLL 開發 本節介紹您在開發自己的 DLL 時應該考慮的問題和要求。 DLL 的類型當您在應用程式中載入 DLL 時,可以使用兩種連結方法來調用導出的 DLL 函式。這兩種連結方法是載入時動態連結和運行時動態連結。 載入時動態連結在載入時動態連結中,應用程式像調用本地函式一樣對導出的 DLL 函式進行顯式調用。要使用載入時動態連結,請在編譯和連結應用程式時提供頭檔案 (.h) 和導入庫檔案 (.lib)。當您這樣做時,連結器將向系統提供載入 DLL 所需的信息,並在載入時解析導出的 DLL 函式的位置。 運行時動態連結在運行時動態連結中,應用程式調用
LoadLibrary 函式或
LoadLibraryEx 函式以在運行時載入 DLL。成功載入 DLL 後,可以使用
GetProcAddress 函式獲得要調用的導出的 DLL 函式的地址。在使用運行時動態連結時,無需使用導入庫檔案。下面的列表說明了有關何時使用載入時動態連結以及何時使用運行時動態連結的應用程式條件: 啟動性能如果應用程式的初始啟動性能很重要,則應使用運行時動態連結。 易用性在載入時動態連結中,導出的 DLL 函式類似於本地函式。這使您可以方便地調用這些函式。 應用程式邏輯在運行時動態連結中,應用程式可以分支,以便按照需要載入不同的模組。在開發多語言版本時,這一點很重要。DLL 入口點在創建 DLL 時,可以有選擇地指定入口點函式。當進程或執行緒將它們自身附加到 DLL 或者將它們自身從 DLL 分離時,將調用入口點函式。您可以使用入口點函式根據 DLL 的需要來初始化數據結構或者銷毀數據結構。此外,如果應用程式是多執行緒的,則可以在入口點函式中使用執行緒本地存儲 (TLS) 來分配各個執行緒專用的記憶體。下面的代碼是一個 DLL 入口點函式的示例。 BOOL APIENTRY DllMain( HANDLE hModule, // Handle to DLL module DWORD ul_reason_for_call, // Reason for calling function LPVOID lpReserved ) // Reserved{ switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACHED: // A process is loading the DLL. break; case DLL_THREAD_ATTACHED: // A process is creating a new thread. break; case DLL_THREAD_DETACH: // A thread exits normally. break; case DLL_PROCESS_DETACH: // A process unloads the DLL. break; } return TRUE; }
當入口點函式返回 FALSE 值時,如果您使用的是載入時動態連結,則應用程式不啟動。如果您使用的是運行時動態連結,則只有個別 DLL 不會載入。
入口點函式只應執行簡單的初始化任務,不應調用任何其他 DLL 載入函式或終止函式。例如,在入口點函式中,不應直接或間接調用 LoadLibrary 函式或 LoadLibraryEx 函式。此外,不應在進程終止時調用 FreeLibrary 函式。
注意 :在多執行緒應用程式中,請確保將對 DLL 全局數據的訪問進行同步(執行緒安全),以避免可能的數據損壞。為此,請使用 TLS 為各個執行緒提供唯一的數據。 導出 DLL 函式要導出 DLL 函式,您可以嚮導出的 DLL 函式中添加函式關鍵字,也可以創建
模組定義檔案 (.def) 以列出導出的 DLL 函式。
要使用函式關鍵字,您必須使用以下關鍵字來聲明要導出的各個函式: __declspec(dllexport)
要在應用程式中使用導出的 DLL 函式,您必須使用以下關鍵字來聲明要導入的各個函式: __declspec(dllimport)
通常情況下,您最好使用一個包含 define 語句和 ifdef 語句的頭檔案,以便分隔導出語句和導入語句。
您還可以使用模組定義檔案來聲明導出的 DLL 函式。當您使用模組定義檔案時,您不必嚮導出的 DLL 函式中添加函式關鍵字。在模組定義檔案中,您可以聲明 DLL 的 LIBRARY 語句和 EXPORTS 語句。下面的代碼是一個定義檔案的示例。 // SampleDLL.def//LIBRARY "sampleDLL"EXPORTS HelloWorld
示例 DLL 和應用程式在 Microsoft
Visual C++ 6.0 中,可以通過選擇“Win32 動態程式庫”項目類型或“MFC 應用程式嚮導 (dll)”來創建 DLL。
下面的代碼是一個在 Visual C++ 中通過使用“Win32 動態程式庫”項目類型創建的 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() ;#else extern __declspec(dllimport) void HelloWorld() ;#endif #endif
下面的代碼是一個“Win32 應用程式”項目的示例,該示例調用 SampleDLL DLL 中的導出 DLL 函式。 // SampleApp.cpp //#include "stdafx.h" #include "sampleDLL.h"int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ HelloWorld(); return 0; }
注意 :在載入時動態連結中,您必須連結在生成 SampleDLL 項目時創建的 SampleDLL.lib 導入庫。
在運行時動態連結中,您應使用與以下代碼類似的代碼來調用 SampleDLL.dll 導出 DLL 函式。 ...typedef VOID (*DLLPROC) (LPTSTR);... HINSTANCE hinstDLL;DLLPROC HelloWorld;BOOL fFreeDLL; hinstDLL = LoadLibrary("sampleDLL.dll");if (hinstDLL != NULL){ HelloWorld = (DLLPROC) GetProcAddress(hinstDLL, "HelloWorld"); if (HelloWorld != NULL) (HelloWorld); fFreeDLL = FreeLibrary(hinstDLL);}...
當您編譯和連結 SampleDLL 應用程式時,Windows 作業系統將按照以下順序在下列位置中搜尋 SampleDLL DLL: 應用程式資料夾 當前資料夾 Windows
系統資料夾 注意:GetSystemDirectory 函式返回 Windows 系統資料夾的路徑。 Windows 資料夾注意:GetWindowsDirectory 函式返回 Windows 資料夾的路徑.
.NET Framework 程式集 在引入 Microsoft .NET 和 .NET Framework 以後,編譯NET Framework的類成DLL檔案,優點是安全保密和快速調用,大多數與 DLL 相關聯的問題已經通過使用程式集消除了。程式集是在 .NET
公共語言運行庫 (CLR) 控制之下運行的邏輯功能單元。程式集實際上是作為 .dll 檔案或 .exe 檔案存在的。但是,在內部,程式集與 Microsoft Win32 DLL 大不相同。程式集檔案包含程式集清單、類型元數據、Microsoft 中間語言 (MSIL) 代碼和其他資源。程式集清單包含程式集元數據,以提供使程式集成為自描述程式集所需的全部信息。程式集清單中包含以下信息: 程式集名稱 版本信息 區域性信息 強名稱信息 程式集檔案列表 類型引用信息 引用和依賴程式集信息程式集中包含的 MSIL 代碼是無法直接執行的,需要通過 CLR 來執行。默認情況下,當您創建一個程式集時,該程式集是應用程式專有的。要創建共享程式集,需要為該程式集分配強名稱,然後在
全局程式集快取 中發布該程式集。
下表說明了程式集的一些功能,並將其與 Win32 DLL 的功能進行了比較: 自描述當您創建程式集時,CLR 運行該程式集所需的全部信息都包含在程式集清單中。程式集清單包含一個依賴程式集列表。因此,CLR 可以維護一組在應用程式中使用的一致的程式集。在 Win32 DLL 中,當您使用共享 DLL 時,無法維護應用程式中使用的一組 DLL 之間的一致性。 版本控制在程式集清單中,版本信息由 CLR 記錄和實施。另外,可以通過
版本策略 來實施版本特定用法。在 Win32 DLL 中,無法由作業系統實施版本控制。相反,您必須確保 DLL 向後兼容。 並行部署程式集支持並行部署。一個應用程式可以使用一個版本的程式集,而另一個應用程式可以使用另一不同版本的程式集。從 Windows 2000 開始,通過將 DLL 放置到應用程式資料夾中支持並行部署。另外,Windows 檔案保護能夠防止系統 DLL 被未經授權的代理改寫或替換。 獨立和隔離通過使用程式集開發的應用程式可以是獨立的,並且與計算機中正在運行的其他應用程式隔離。這一特性有助於創建零干擾安裝。 執行程式集在程式集清單所提供的並且由 CLR 控制的安全許可權下運行。 語言無關性可以通過使用任何一種受支持的 .NET 語言來開發程式集。例如,可以在 Microsoft Visual C# 中開發程式集,然後在 Microsoft
Visual Basic .net 項目中使用該程式集。
DLL內容說明 USER32.DLL------於windows管理有關的函式。訊息、選單、游標、
計時器 、通信和其他大多數非現實函式都可以從這裡找到;
GDI32.DLL-------圖形設備接口庫。於設備輸出有關的函式:大多數繪圖、顯示場景、
圖元檔案 、坐標及其字型函式都可以從這裡找到;
COMDLG32.DLL\LZ32.DLL\VERSION.DLL\---這都是提供一些附加函式的庫,包括通用對話框、檔案壓縮、版本控制的支持;
COMCTL32.DLL --------一個新的windows控制項集合,比如TreeView和RichTextBox等等,最初這個是為了win95而製作的,但是現在也使用於NT中;
MAPI32.DLL---------提供了一套電子郵件的專用函式;
NETAPI32.DLL--------提供了一套訪問和控制網路的函式;
ODBC32.DLL--------ODBC功能的DLL之一;
WINMM.DLL--------是多媒體控制訪問函式集合;
DLL(Delay Locked Loop,延時鎖定迴路提供一個數據濾波信號;