? | 概要 | ||||||||||||||||||||||||||
? | 更多信息
| ||||||||||||||||||||||||||
? | 參考 |
![]() | 概要 | |
![]() | 更多信息 | |
![]() | 參考 |
? | 導出函數(shù):這些函數(shù)由其他模塊調(diào)用。 |
? | 內(nèi)部函數(shù):這些函數(shù)僅從定義它們的 DLL 中調(diào)用。 |
? | 加載時動態(tài)鏈接:調(diào)用方模塊執(zhí)行顯式調(diào)用以導出 DLL 函數(shù)。為 DLL 創(chuàng)建導入庫,然后將 DLL 鏈接到應用程序。在加載應用程序時,導入庫提供加載 DLL 和查找導出的 DLL 函數(shù)所需的信息。 |
? | 運行時動態(tài)鏈接:在運行時加載 DLL 時,調(diào)用方模塊使用 LoadLibrary 函數(shù)或 LoadLibraryEx 函數(shù)。調(diào)用方模塊調(diào)用 GetProcAddress 函數(shù)以獲取導出的 DLL 函數(shù)的地址。 |
1. | 當前進程的可執(zhí)行程序所在的目錄。 |
2. | 當前目錄。 |
3. | Windows 系統(tǒng)目錄。(GetSystemDirectory 函數(shù)獲取 Windows 系統(tǒng)目錄的路徑。) |
4. | Windows 目錄。(GetWindowsDirectory 函數(shù)獲取 Windows 目錄的路徑。) |
5. | PATH 環(huán)境變量中列出的目錄。 注意:LIBPATH 環(huán)境變量不用于搜索。 |
? | DLL 可節(jié)省內(nèi)存并減少交換。 通過在內(nèi)存中共享 DLL 的單個副本,多個進程可以同時使用一個 DLL。相比之下,對于使用靜態(tài)鏈接庫構(gòu)建的每一個應用程序,Windows 都要在內(nèi)存中為其加載庫代碼的一個副本。 |
? | DLL 可節(jié)省磁盤空間。 多個應用程序可以共享磁盤上的一個 DLL 副本。相比之下,使用靜態(tài)鏈接庫構(gòu)建的每一個應用程序都需要讓鏈接到程序文件映像的庫代碼作為一個單獨的專用副本。 |
? | DLL 可節(jié)省時間。 更改 DLL 中的函數(shù)時,只要函數(shù)的參數(shù)和返回值不變,就不必重新編譯或重新鏈接使用這些函數(shù)的應用程序。但是,如果您使用靜態(tài)鏈接的對象代碼,則在更改函數(shù)后必須重新鏈接應用程序。 |
? | DLL 可以共享函數(shù)。 在 Win32 中,DLL 可以共享函數(shù)。默認情況下,數(shù)據(jù)對于每個進程來說是獨立的。但是,靜態(tài)庫包含針對每一個進程的單獨的數(shù)據(jù)副本和函數(shù)。 |
? | 將程序劃分為可按需加載的單獨模塊。 |
? | 存儲特定于語言或特定于區(qū)域的資源。 |
? | 使您自己的應用程序能夠使用核心代碼庫。 |
? | 生成進程內(nèi) COM 對象或 ActiveX 控件 (OCX)。 |
? | 將 OLE 對象用作進程內(nèi) DLL。這一用法可改進 OLE 鏈接的性能。 |
? | 使用控制面板擴展或使用某些類型的驅(qū)動程序。 |
? | 如果計劃服務(wù)的服務(wù)帳戶密碼與域用戶管理器帳戶的密碼不同,則您在計劃服務(wù)時可能會收到以下初始化錯誤信息: Initialization of dynamic link library c:\winnt\system32\KERNEL32.dll failed.Process is terminating abnormally 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 250265 使用 Cmd.exe 運行 AT 計劃命令時出現(xiàn) Kernel32.dll 動態(tài)鏈接庫初始化錯誤 |
? | 如果不斷加載和卸載 Crypt32.dll,則在加載 Crypt32.dll 時將分配傳輸層安全性 (TLS),但在卸載 Crypt32.dll 時卻不釋放它。此行為可能導致一般性保護錯誤 (GPF) 錯誤,并且您可能會收到以下錯誤信息: Initialization of the dynamic link library C:\WINNT40\System32\CRYPT32.dll failed.The process is terminating abnormally. 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 212825 SMS:一般性保護錯誤:Initialization of CRYPT32.DLL Failed(CRYPT32.DLL 初始化失?。? |
? | 如果您將計算機升級到 McAfee VirusScan 6.0,則可能會在啟動 Outlook 2000 后的三分鐘內(nèi)收到以下錯誤信息: Outlook.exe. DLL initialization failed.Initialization of c:\winnt\system32\compstui.dll. Process is terminating abnormally. 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 310413 OL2000:升級到 McAfee VirusScan 6.0 后 Outlook 2000 發(fā)生 DLL 初始化錯誤 |
? | 如果您將 Windows NT Mail 或 MSMail32.exe 設(shè)置為按計劃啟動,計劃服務(wù)可能被記錄為系統(tǒng)以外的其他內(nèi)容,而且您可能會收到以下錯誤信息: Initialization of the Dynamic Link Library OLECLI32.dll failed Abnormally 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 133476 Windows NT 郵件錯誤信息:Initialization of the Dynamic Link...(動態(tài)鏈接的初始化...) |
? | 如果遠程訪問服務(wù) (RAS) 文件或調(diào)制解調(diào)器文件丟失或損壞,并且您試圖打開控制面板,則可能會收到以下錯誤信息: Explorer.exe - DLL Initialization Failed Initialization of the dynamic link library E:\WINNT\System32\RASSCRPT.dll failed.The process is terminating abnormally. 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 184443 錯誤信息:Explorer.exe - DLL Initialization Failed...(Explorer.exe — DLL 初始化失敗...) |
? | 如果系統(tǒng)內(nèi)存不足,無法為正在啟動的服務(wù)創(chuàng)建新的桌面堆棧,您可能會收到以下錯誤信息: ServiceName - DLL initialization failure Initialization of the dynamic link library c:\windows\system32\user32.dll failed.The process is terminating abnormally. 有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 142676 解決 User32.dll 初始化失敗錯誤 |
? | 如果程序使用導入庫來加載 Winmm.dll 文件,則 Winmm.dll 在程序啟動時加載。在這種情況下,可能會在啟動程序時出現(xiàn)延遲。因此,如果使用批處理文件多次啟動此程序,性能會顯著下降。 |
? | 如果程序使用 LoadLibrary 加載 Winmm.dll 文件,則 Winmm.dll 僅在程序需要時才加載。例如,如果在您打開菜單時 Explorer.exe 播放聲音,則在第一次播放聲音時加載 Winmm.dll 文件。在這種情況下,可能會在程序加載 Winmm.dll 文件時出現(xiàn)延遲。 |
? | 將調(diào)用應用程序在加載后立刻需要的所有函數(shù)放入一個 DLL,然后將該調(diào)用應用程序隱式鏈接到此 DLL。 |
? | 將調(diào)用應用程序不立即需要的函數(shù)放入另一個 DLL,然后將該應用程序顯式鏈接到此 DLL。 |
? | Dependency Walker Dependency Walker 不僅僅是一個故障排除實用工具。Dependency Walker 提供了許多關(guān)于某一特定應用程序的模塊布局的寶貴信息。此實用工具還提供關(guān)于每個模塊的詳細信息。有關(guān)更多信息,請參閱本文的“aspx?scid=kb;zh-cn;815065#6">DLL 依賴性”部分。 |
? | DLL Universal Problem Solver 工具出現(xiàn) DLL 文件版本沖突問題(也稱為“DLL Hell”問題)時,可以使用 DLL Universal Problem Solver (DUPS) 工具查找這些問題并進行修復。DUPS 程序包是一個實用工具集,使用它可以跟蹤和比較多臺基于 Windows 的計算機上的 DLL 版本。有關(guān)更多信息,請訪問下面的 Microsoft Web 站點: |
? | RegSvr32 使用 Regsvr32 工具 (Regsvr32.exe) 可注冊或注銷 OLE 控件,例如可自行注冊的 DLL 控制文件或 ActiveX 控件 (OCX) 文件。為排查 Windows、Microsoft Internet Explorer 或其他程序中的故障,您可能必須注冊或注銷這些文件。有關(guān)其他信息,請單擊下面的文章編號,以查看 Microsoft 知識庫中相應的文章: 249873 Regsvr32 用法和錯誤消息的說明 |
? | OLE/COM 對象查看器使用 OLE/COM 對象查看器,可通過讀取類型庫來查看控件(DLL 或 OCX 文件)的接口。有關(guān)更多信息,請訪問下面的 Microsoft Web 站點: |
? | .Net Framework 工具 Microsoft .Net Framework SDK 工具旨在使您創(chuàng)建、部署和管理使用 .Net Framework 的應用程序和組件的過程更輕松。.Net Framework 提供四組工具:配置和部署工具、調(diào)試工具、安全工具和常規(guī)工具。有關(guān)更多信息,請訪問下面的 Microsoft Web 站點: |
? | 這些 EXE 或 DLL 文件中的代碼是由語言編譯器生成的。此代碼不是 x86 計算機代碼或?qū)S糜谌魏翁囟?CPU 操作系統(tǒng)的計算機代碼。該代碼是用 Microsoft 中間語言 (MSIL) 生成的。MSIL 可以用匯編語言編寫。Microsoft 提供了 MSIL 匯編程序 (ILAsm.exe) 和 MSIL 反匯編程序 (ILDasm.exe)。 |
? | 此 DLL 或 EXE 文件包含編譯器產(chǎn)生的元數(shù)據(jù)。公共語言運行庫使用此元數(shù)據(jù)查找和加載文件中的類類型,確定對象實例在內(nèi)存中的布局,解析方法調(diào)用和字段引用,將 MSIL 轉(zhuǎn)換為本機代碼,執(zhí)行安全設(shè)置。 |
? | 您生成的組件不僅僅是 EXE 文件或 DLL 文件。它們是重新使用和部署的基本單位,是 .Net 中的一個程序集。您可以生成單文件程序集或多文件程序集。在單文件程序集中,程序集的文件擴展名是 .exe 或 .dll。 多文件程序集是這樣一種思想:通過將一個可重用組件的邏輯概念和物理概念分離開來,將代碼劃分到多個文件中以滿足您的需求。不過,您仍然可以保留集合作為版本控制和部署的一個單位。例如,如果您使用多文件程序集,則可以使用增量和按需下載。 |
? | 通過使用程序集,開發(fā)人員和管理員能夠表示程序的各組件之間嚴格的版本依賴性。由于各組件是自描述的,所以您可以創(chuàng)建無影響安裝。 在安裝新應用程序的組件時,它們可能覆蓋早期的應用程序的組件。如果發(fā)生此覆蓋,早期的應用程序可能會運行不正?;蛲V惯\行。.Net Framework 體系結(jié)構(gòu)讓應用程序的各組件保持獨立,這樣應用程序始終能夠加載正確的組件。因此,在安裝后能按預期運行的應用程序?qū)⒗^續(xù)運行。(此功能解決了“DLL Hell”問題。) |
? | 程序集是 .Net 安全系統(tǒng)的一部分。程序集是申請和授予權(quán)限的單位。為了正確地在 .Net Framework 中強制實施版本控制、部署和安全功能,程序集起到了解析范圍的作用,用于解析對類型的引用。 |
1. | 標識函數(shù)名稱和導出該函數(shù)的 DLL 的名稱。例如,通過指定 User32.dll 中的 MessageBox 函數(shù),您可以標識函數(shù) (MessageBox) 和函數(shù)的位置(User32.dll、User32 或 user32)。 |
2. | 創(chuàng)建一個類以包裝 DLL 函數(shù)。在類中為要調(diào)用的每個 DLL 函數(shù)定義一個靜態(tài)方法。例如,您可以調(diào)用 User32.dll 中的 MessageBox 函數(shù),如下例所示: |
3. | 使用 DllImportAttribute 屬性標識 DLL 和函數(shù)。使用外部“C”標記包裝方法或函數(shù)。 |
4. | 通過傳遞在托管代碼中定義的類的成員,調(diào)用托管類中的方法。 例如,將 MySystemTime 類的成員(這些成員是按順序定義的)傳遞到 User32.dll 文件中的 GetSystemTime 方法,如下例中所示: |
1. | 將 .Net 程序集反匯編為對應的中間語言 (IL) 源代碼和元數(shù)據(jù)。 |
2. | 重新匯編對等的 .Net 程序集中的 IL 代碼、元數(shù)據(jù)和資源。 |
public static void HelloWorld(){Console.WriteLine("Hello World!");}public static void HelloMyWorld(){Console.WriteLine("Hello My World!");}
要對該程序集進行反匯編,請使用以下命令行: .module MyAssembly.dll// MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}.imagebase 0x11000000.subsystem 0x00000003.file alignment 512.corflags 0x00000001
要進行更改,請執(zhí)行下列操作: 1. | 要定義一個 v-table 修正并使之包含的插槽與要導出的方法一樣多(上例中有兩個方法),請按如下所示更改清單: |
2. | .corflags 指令設(shè)置運行庫頭文件標志。默認情況下,.corflags 指令指定值 1。 此值等于 COMIMAGE_FLAGS_ILONLY 標志(在 .Net Framework SDK 中的 CorHdr.h 包含文件中定義)。 設(shè)置此標志后,Windows XP 加載程序會忽略該程序集文件的主要部分,而且不進行修正。 在您嘗試使用程序集導出時,這會導致致命錯誤。 所以,如果您希望程序集在 Windows XP 上運行,必須指定 COMIMAGE_FLAGS_32BITREQUIRED 標志(此值為 2): |
.method public hidebysig static voidHelloWorld() cil managed{// Code size 11 (0xb).maxstack 1.line 18:4IL_0000: ldstr "Hello World!"IL_0005: call void [mscorlib]System.Console::WriteLine(string).line 19:3IL_000a: ret} // end of method Class1::HelloWorld.method public hidebysig static voidHelloMyWorld() cil managed{// Code size 11 (0xb).maxstack 1.line 23:4IL_0000: ldstr "Hello My World!"IL_0005: call void [mscorlib]System.Console::WriteLine(string).line 24:3IL_000a: ret} // end of method Class1::HelloMyWorld
要讓這些方法作為非托管導出,請對它們進行如下更改:.method public hidebysig static voidHelloWorld() cil managed{// Code size 11 (0xb).maxstack 1.line 18:4.vtentry 1:1.export [1] as HelloWorldIL_0000: ldstr "Hello World!"IL_0005: call void [mscorlib]System.Console::WriteLine(string).line 19:3IL_000a: ret} // end of method Class1::HelloWorld.method public hidebysig static voidHelloMyWorld() cil managed{// Code size 11 (0xb).maxstack 1.line 23:4.vtentry 1:2.export [2] as HelloMyWorldIL_0000: ldstr "Hello My World!"IL_0005: call void [mscorlib]System.Console::WriteLine(string).line 24:3IL_000a: ret} // end of method Class1::HelloMyWorld
每個方法需要一個 .vtentry 指令以將該方法鏈接到 v-table 修正(粗體顯示指定的插槽號),還需要一個 .export 指令以指定導出的名稱。es:MyAssembly.resMicrosoft (R) .Net Framework IL Assembler. Version 1.0.3705.0Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.Assembling ‘MyAssembly.il‘ , no listing file, to DLL --> ‘MyAssembly_new.dll‘Source file is ANSIAssembled method Class1::MainAssembled method Class1::HelloWorldAssembled method Class1::HelloMyWorldAssembled method Class1::.ctorCreating PE fileEmitting members:GlobalClass 1 Methods: 4;Resolving member refs: 1 -> 1 defs, 0 refsWriting PE fileOperation completed successfully
使用反向 PInvoke 時可能遇到的主要困難是維護問題。如果要通過創(chuàng)造性往返修改編譯器生成的程序集,請重新手動更新程序集以導出例程。