免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
什么是DLL? Visual C 編程資料
本主題的內(nèi)容
? 概要
? 更多信息
? 什么是 DLL?
? DLL 和靜態(tài)庫
? DLL 入口點
? DLL 問題和故障排除工具
? 初始化問題
? 依賴性問題
? 性能問題
? 故障排除工具
? DLL 依賴性
? Win32 與 .Net 程序集的比較
? .Net 連接的客戶端應用程序使用 Win32 DLL 導出 (PInvoke)
? Win32 客戶端應用程序使用 .Net 程序集導出(反向 PInvoke)
? 從程序集公開方法
? 參考
本頁內(nèi)容
概要
更多信息
參考

概要

Microsoft Windows 和 Windows 應用程序使用動態(tài)鏈接庫 (DLL) 執(zhí)行功能,例如注冊和注銷(DllRegisterServer、DllUnregisterServer)或者在內(nèi)存中加載和卸載(DllGetClassObject、DllCanUnloadNow)對象、進程和數(shù)據(jù)等。

本文將討論動態(tài)鏈接、入口點、依賴性、動態(tài)庫與靜態(tài)庫的區(qū)別、DLL 問題和故障排除。本文還包含 Win32 與 .Net 程序集的比較。

aspx?scid=kb;zh-cn;815065#toc">返回頁首

更多信息

什么是 DLL?

動態(tài)鏈接庫 (DLL) 是包含函數(shù)和數(shù)據(jù)的模塊的集合。程序文件(如 .exe 文件或 .dll 文件)在運行時加載這些模塊(亦即所需的模塊映射到調(diào)用進程的地址空間)。下面兩類函數(shù)定義了 DLL:
? 導出函數(shù):這些函數(shù)由其他模塊調(diào)用。
? 內(nèi)部函數(shù):這些函數(shù)僅從定義它們的 DLL 中調(diào)用。
DLL 還導出數(shù)據(jù)。不過,這些數(shù)據(jù)由相應的函數(shù)使用。

動態(tài)鏈接和靜態(tài)鏈接

動態(tài)鏈接包括系統(tǒng)在加載或運行時查找導出的 DLL 函數(shù)的代碼所需的信息。

在靜態(tài)鏈接中,鏈接器將庫函數(shù)的代碼復制到調(diào)用 DLL 的每個模塊。

可以通過下列方式調(diào)用 DLL 中的函數(shù):
? 加載時動態(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ù)的地址。
在鏈接時,Windows 搜索預安裝的一組 DLL,例如性能庫 (Kernel32.dll) 和安全庫 (User32.dll)。然后,Windows 按以下順序搜索 DLL:
1. 當前進程的可執(zhí)行程序所在的目錄。
2. 當前目錄。
3. Windows 系統(tǒng)目錄。(GetSystemDirectory 函數(shù)獲取 Windows 系統(tǒng)目錄的路徑。)
4. Windows 目錄。(GetWindowsDirectory 函數(shù)獲取 Windows 目錄的路徑。)
5. PATH 環(huán)境變量中列出的目錄。

注意:LIBPATH 環(huán)境變量不用于搜索。
aspx?scid=kb;zh-cn;815065#toc">返回頁首

DLL 和靜態(tài)庫

? 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ù)。
aspx?scid=kb;zh-cn;815065#toc">返回頁首

DLL 入口點

DLL 有一個特殊的入口點(DllMain 函數(shù)),它在附加和分離進程和線程時運行。此行為允許根據(jù)需要創(chuàng)建和銷毀數(shù)據(jù)結(jié)構(gòu)。文件擴展名為 .ocx、.cpl.drv 的文件類型也是 DLL,盡管文件擴展名已改變。在 Windows 2.x 和 Windows 3.x 中,每個 DLL 都只有一個數(shù)據(jù)段實例,而不管有多少應用程序。在 Windows 32 中,可以將 DLL 標記為共享以導致相同的行為。但是,每個進程的默認設(shè)置是擁有 DLL 數(shù)據(jù)的專用副本。
您可以通過創(chuàng)建 DLL 實現(xiàn)以下目的:
? 將程序劃分為可按需加載的單獨模塊。
? 存儲特定于語言或特定于區(qū)域的資源。
? 使您自己的應用程序能夠使用核心代碼庫。
? 生成進程內(nèi) COM 對象或 ActiveX 控件 (OCX)。
? 將 OLE 對象用作進程內(nèi) DLL。這一用法可改進 OLE 鏈接的性能。
? 使用控制面板擴展或使用某些類型的驅(qū)動程序。
要生成 DLL,請使用 DllMain 函數(shù)(而不是程序文件)替換 WinMain 函數(shù)。

要在 Win16 中導出函數(shù),請將 FAR EXPORT 添加到所有導出的 DLL 函數(shù)(在 Win32 中不要求這樣做)。許多 32 位編譯器提供了函數(shù)聲明符,例如 __declspec(dllexport)__declspec(dllimport)。這些函數(shù)聲明符出現(xiàn)在函數(shù)聲明之前以代替調(diào)用。不過,定義必須僅指定 dllexport 屬性。

aspx?scid=kb;zh-cn;815065#toc">返回頁首

DLL 問題和故障排除工具

初始化問題

在 DLL 初始化過程中,您可能會遇到下列一個或多個問題:
? 如果計劃服務(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 初始化失敗錯誤
aspx?scid=kb;zh-cn;815065#toc">返回頁首

依賴性問題

如果您沒有等到所有系統(tǒng)服務(wù)開始運行就啟動您的服務(wù),可能會遇到依賴性問題。例如,服務(wù)依賴于其他服務(wù)或驅(qū)動程序。這些服務(wù)或驅(qū)動程序又轉(zhuǎn)而依賴于另外一些服務(wù)或驅(qū)動程序。更確切地說,RasApi32.dll 隱式依賴于 RAS 服務(wù)。使用 Rasapi32.dll 上的 LoadLibrary 的一個 Windows NT 服務(wù)使該服務(wù)依賴于 RAS 服務(wù)。

在您對項目進行更改時,定期通過“項目”菜單掃描所有依賴項以確保依賴性列表的準確性。如果您在執(zhí)行依賴性掃描之前未保存對項目中文件所做的更改,新的依賴項不會顯示在列表中。

aspx?scid=kb;zh-cn;815065#toc">返回頁首

性能問題

如果加載應用程序的同時加載隱式鏈接到該應用程序的 DLL,則會出現(xiàn)性能問題。例如,當運行 Windows 2000 的計算機在內(nèi)存中加載 Winmm.dll 文件時,可能會出現(xiàn)延遲。此延遲可能會在不同的時間發(fā)生,具體取決于 Winmm.dll 文件是如何加載的:
? 如果程序使用導入庫來加載 Winmm.dll 文件,則 Winmm.dll 在程序啟動時加載。在這種情況下,可能會在啟動程序時出現(xiàn)延遲。因此,如果使用批處理文件多次啟動此程序,性能會顯著下降。
? 如果程序使用 LoadLibrary 加載 Winmm.dll 文件,則 Winmm.dll 僅在程序需要時才加載。例如,如果在您打開菜單時 Explorer.exe 播放聲音,則在第一次播放聲音時加載 Winmm.dll 文件。在這種情況下,可能會在程序加載 Winmm.dll 文件時出現(xiàn)延遲。
要提高性能,請在加載時使用優(yōu)化技巧。另外,可將 DLL 分為兩個 DLL:
? 將調(diào)用應用程序在加載后立刻需要的所有函數(shù)放入一個 DLL,然后將該調(diào)用應用程序隱式鏈接到此 DLL。
? 將調(diào)用應用程序不立即需要的函數(shù)放入另一個 DLL,然后將該應用程序顯式鏈接到此 DLL。
aspx?scid=kb;zh-cn;815065#toc">返回頁首

故障排除工具

支持使用下列工具進行故障排除:
? 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 站點:
asp?url=/library/en-us/dnsetup/html/dlldanger1.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsetup/html/dlldanger1.asp
? 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 站點:
asp?url=/library/en-us/vccore/html/vcrefusingolecomobjectviewertoviewcontrolsinterfaces.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcrefUsingOLECOMObjectViewerToViewControlsInterfaces.asp
? .Net Framework 工具 Microsoft .Net Framework SDK 工具旨在使您創(chuàng)建、部署和管理使用 .Net Framework 的應用程序和組件的過程更輕松。.Net Framework 提供四組工具:配置和部署工具、調(diào)試工具、安全工具和常規(guī)工具。有關(guān)更多信息,請訪問下面的 Microsoft Web 站點:
asp?url=/library/en-us/cptools/html/cpconnetframeworktools.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconnetframeworktools.asp
aspx?scid=kb;zh-cn;815065#toc">返回頁首

DLL 依賴性

通過使用 Dependency Walker,您可以查看應用程序?qū)?DLL 的依賴情況。例如,Depends.exe 包含在 Visual C++ .Net 中。Depends.exe 安裝在 \Microsoft Visual Studio .Net 2003\Common7\Tools\Bin 文件夾中。僅當您在 Visual C++ .Net 自定義安裝的 Visual C++ 工具類別中選擇了 Win32 Platform SDK 工具時,才可以安裝 Depends.exe 可執(zhí)行文件。

通過使用 Depends.exe 或 DUMPBIN 實用工具并使用 /DEPENDENTS 選項,可以查看靜態(tài)鏈接到您的應用程序的 DLL 列表和延遲加載的 DLL 的列表。要查看動態(tài)加載了哪些 DLL(如 ActiveX 控件),請使用 Depends.exe 的信息摘要功能。有關(guān)更多信息,請訪問下面的 Microsoft Web 站點:
asp?url=/library/en-us/vccore/html/vccondeterminingwhichdllstoredistribute.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vccondeterminingwhichdllstoredistribute.asp
aspx?scid=kb;zh-cn;815065#toc">返回頁首

Win32 與 .Net 程序集的比較

.Net Framework 中,程序集是一個邏輯 EXE 或 DLL。下面是程序集與 Win32 DLL 相比較二者之間的不同之處:
? 這些 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 中強制實施版本控制、部署和安全功能,程序集起到了解析范圍的作用,用于解析對類型的引用。
清單 中描述了程序集的各個組件。清單是一個數(shù)據(jù)塊,它列出程序集的文件,并控制著向程序集之外公開哪些類型和資源。例如,某些類型可能保留為僅在程序集內(nèi)使用。其他類型可能能夠?qū)С龅匠绦蚣氖褂谜摺?a target="_blank">.Net Framework 按照在程序集清單中表達的規(guī)則將類型和資源解析為程序集中的實現(xiàn)文件和綁定到從屬程序集。

雖然 .Net Framework 很大而且范圍很廣,但仍然存在可使用 Win32 API 執(zhí)行,而使用 .Net Framework 則無法執(zhí)行的一些功能。例如,您可以使用 Win32 API MessageBeepBeep 在應用程序中包含生成噪音的功能。

aspx?scid=kb;zh-cn;815065#toc">返回頁首

.Net 連接的客戶端應用程序使用 Win32 DLL 導出 (PInvoke)

要通過 .Net 連接的應用程序使用 Win32 DLL 例程,請使用“平臺調(diào)用服務(wù)”機制(也叫平臺調(diào)用或 PInvoke)。此服務(wù)通過在 System.Runtime.InteropServices 命名空間中定義的一個自定義屬性 (DllImportAttribute) 運行。該屬性允許實現(xiàn) DLL 的名稱(和其他必需信息)與一個過程或函數(shù)聲明關(guān)聯(lián)。通過此關(guān)聯(lián),您可以調(diào)用 DLL 例程。組件對象模型 (COM) Interop 支持使用 Interop 封送拆收器自動在托管 .Net 環(huán)境和非托管 Win32 環(huán)境之間封送拆收參數(shù)和返回值。

要使用導出的 DLL 函數(shù),請按照下列步驟操作:
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ù),如下例所示:
using System.Runtime.InteropServices;            [DllImport("user32.dll")]            public static extern int MessageBox(int hWnd, String text,            String caption, uint type);
3. 使用 DllImportAttribute 屬性標識 DLL 和函數(shù)。使用外部“C”標記包裝方法或函數(shù)。
4. 通過傳遞在托管代碼中定義的類的成員,調(diào)用托管類中的方法。 例如,將 MySystemTime 類的成員(這些成員是按順序定義的)傳遞到 User32.dll 文件中的 GetSystemTime 方法,如下例中所示:
void GetSystemTime(SYSTEMTIME* SystemTime);            class Win32API {            [DllImport("Kernel32.dll")]            public static extern void GetSystemTime(MySystemTime st);            }
有關(guān)更多信息,請訪問下面的 Microsoft Web 站點:
asp?url=/library/en-us/cpguide/html/cpconconsumingunmanageddllfunctions.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconconsumingunmanageddllfunctions.asp
aspx?scid=kb;zh-cn;815065#toc">返回頁首

Win32 客戶端應用程序使用 .Net 程序集導出(反向 PInvoke)

要在 Win32 應用程序中使用 .Net 程序集,請使用“反向平臺調(diào)用服務(wù)”機制。 此服務(wù)使用的機制與 PInvoke 使用的機制反向。
通過使用此機制,.Net 中的公共語言運行庫可以向外部 (Win32) 世界公開任何 .Net 方法。此機制執(zhí)行下列操作:
1. .Net 程序集反匯編為對應的中間語言 (IL) 源代碼和元數(shù)據(jù)。
2. 重新匯編對等的 .Net 程序集中的 IL 代碼、元數(shù)據(jù)和資源。
詳細信息

要對 .Net 程序集進行反匯編,您可以使用 Framework SDK 中包含的 .Net Framework IL 反匯編程序 (Ildasm.exe)。 例如,MyAssembly.dll 包含下列獨立例程,即 HelloWorld 和 HelloMyWorld:
public static void HelloWorld(){Console.WriteLine("Hello World!");}public static void HelloMyWorld(){Console.WriteLine("Hello My World!");}
要對該程序集進行反匯編,請使用以下命令行:
ildasm MyAssembly.dll /linenum /out:MyAssembly.il
此命令將生成命名的 IL 文件。它還在 MyAssembly.res 文件中存儲任何非托管資源,在具有程序集元數(shù)據(jù)中指定的名稱的文件中存儲任何托管資源。如果 PDB 文件中包含調(diào)試信息,則 /linenum 選項使 IL 文件包括對原始源代碼行的引用。

aspx?scid=kb;zh-cn;815065#toc">返回頁首

從程序集公開方法

要從程序集公開方法,必須對程序集清單進行某些更改。該清單位于 IL 文件頂部的類聲明之前:
.module MyAssembly.dll// MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}.imagebase 0x11000000.subsystem 0x00000003.file alignment 512.corflags 0x00000001
要進行更改,請執(zhí)行下列操作:
1. 要定義一個 v-table 修正并使之包含的插槽與要導出的方法一樣多(上例中有兩個方法),請按如下所示更改清單:
module MyAssembly.dll            .module MyAssembly.dll            // MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}            .imagebase 0x11000000            .subsystem 0x00000003            .file alignment 512            .corflags 0x00000001            .data VT_01 = int32[2]            .vtfixup [2] int32 fromunmanaged at VT_01
2. .corflags 指令設(shè)置運行庫頭文件標志。默認情況下,.corflags 指令指定值 1。 此值等于 COMIMAGE_FLAGS_ILONLY 標志(在 .Net Framework SDK 中的 CorHdr.h 包含文件中定義)。 設(shè)置此標志后,Windows XP 加載程序會忽略該程序集文件的主要部分,而且不進行修正。 在您嘗試使用程序集導出時,這會導致致命錯誤。 所以,如果您希望程序集在 Windows XP 上運行,必須指定 COMIMAGE_FLAGS_32BITREQUIRED 標志(此值為 2):
module MyAssembly.dll            .module MyAssembly.dll            // MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}            .imagebase 0x11000000            .subsystem 0x00000003            .file alignment 512            .corflags 0x00000002.data VT_01 = int32[2]            .vtfixup [2] int32 fromunmanaged at VT_01
這些方法的 IL 表示當前顯示如下:
.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 指令以指定導出的名稱。

要將代碼重新匯編為 .Net 程序集,請使用 .Net Framework 中包含的 IL 匯編程序 (Ilasm.exe)。使用以下命令行:
C:\Temp\MyAssembly\bin\Debug>ilasm /dll MyAssembly.il /out:MyAssembly_new.dll /r
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)造性往返修改編譯器生成的程序集,請重新手動更新程序集以導出例程。
aspx?scid=kb;zh-cn;815065#toc">返回頁首
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ngen.exe
DLL(Dynamic Link Libraries)
Win32環(huán)境下dll編程原理
靜態(tài)鏈接庫與動態(tài)鏈接庫導出函數(shù)詳解(本文系轉(zhuǎn)載)
dll和lib的區(qū)別
Windows中.exe程序的啟動過程和C/C 運行時庫
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服