国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
什么是DLL
什么是動(dòng)態(tài)鏈接庫?

一、動(dòng)態(tài)鏈接庫的概念
  動(dòng)態(tài)鏈接庫(Dynamic Link Library,縮寫為DLL)是一個(gè)可以被其它應(yīng)用程序共享的程序模塊,其中封裝了一些可以被共享的例程和資源。動(dòng)態(tài)鏈接庫文件的擴(kuò)展名一般是dll,也有可能是drv、sys和fon,它和可執(zhí)行文件(exe)非常類似,區(qū)別在于DLL中雖然包含了可執(zhí)行代碼卻不能單獨(dú)執(zhí)行,而應(yīng)由Windows應(yīng)用程序直接或間接調(diào)用。

  動(dòng)態(tài)鏈接是相對(duì)于靜態(tài)鏈接而言的。所謂靜態(tài)鏈接是指把要調(diào)用的函數(shù)或者過程鏈接到可執(zhí)行文件中,成為可執(zhí)行文件的一部分。換句話說,函數(shù)和過程的代碼就在程序的exe文件中,該文件包含了運(yùn)行時(shí)所需的全部代碼。當(dāng)多個(gè)程序都調(diào)用相同函數(shù)時(shí),內(nèi)存中就會(huì)存在這個(gè)函數(shù)的多個(gè)拷貝,這樣就浪費(fèi)了寶貴的內(nèi)存資源。而動(dòng)態(tài)鏈接所調(diào)用的函數(shù)代碼并沒有被拷貝到應(yīng)用程序的可執(zhí)行文件中去,而是僅僅在其中加入了所調(diào)用函數(shù)的描述信息(往往是一些重定位信息)。僅當(dāng)應(yīng)用程序被裝入內(nèi)存開始運(yùn)行時(shí),在Windows的管理下,才在應(yīng)用程序與相應(yīng)的DLL之間建立鏈接關(guān)系。當(dāng)要執(zhí)行所調(diào)用DLL中的函數(shù)時(shí),根據(jù)鏈接產(chǎn)生的重定位信息,Windows才轉(zhuǎn)去執(zhí)行DLL中相應(yīng)的函數(shù)代碼。

  一般情況下,如果一個(gè)應(yīng)用程序使用了動(dòng)態(tài)鏈接庫,Win32系統(tǒng)保證內(nèi)存中只有DLL的一份復(fù)制品,這是通過內(nèi)存映射文件實(shí)現(xiàn)的。DLL首先被調(diào)入Win32系統(tǒng)的全局堆棧,然后映射到調(diào)用這個(gè)DLL的進(jìn)程地址空間。在Win32系統(tǒng)中,每個(gè)進(jìn)程擁有自己的32位線性地址空間,如果一個(gè)DLL被多個(gè)進(jìn)程調(diào)用,每個(gè)進(jìn)程都會(huì)收到該DLL的一份映像。與16位Windows不同,在Win32中DLL可以看作是每個(gè)進(jìn)程自己的代碼。

  二、動(dòng)態(tài)鏈接庫的優(yōu)點(diǎn)

  1. 共享代碼、資源和數(shù)據(jù)

   使用DLL的主要目的就是為了共享代碼,DLL的代碼可以被所有的Windows應(yīng)用程序共享。

  2. 隱藏實(shí)現(xiàn)的細(xì)節(jié)

   DLL中的例程可以被應(yīng)用程序訪問,而應(yīng)用程序并不知道這些例程的細(xì)節(jié)。

  3. 拓展開發(fā)工具如Delphi的功能

  由于DLL是與語言無關(guān)的,因此可以創(chuàng)建一個(gè)DLL,被C++、VB或任何支持動(dòng)態(tài)鏈接庫的語言調(diào)用。這樣如果一種語言存在不足,就可以通過訪問另一種語言創(chuàng)建的DLL來彌補(bǔ)。

  三、動(dòng)態(tài)鏈接庫的實(shí)現(xiàn)方法

  1. Load-time Dynamic Linking

  這種用法的前提是在編譯之前已經(jīng)明確知道要調(diào)用DLL中的哪幾個(gè)函數(shù),編譯時(shí)在目標(biāo)文件中只保留必要的鏈接信息,而不含DLL函數(shù)的代碼;當(dāng)程序執(zhí)行時(shí),利用鏈接信息加載DLL函數(shù)代碼并在內(nèi)存中將其鏈接入調(diào)用程序的執(zhí)行空間中,其主要目的是便于代碼共享。

  2. Run-time Dynamic Linking

  這種方式是指在編譯之前并不知道將會(huì)調(diào)用哪些DLL函數(shù),完全是在運(yùn)行過程中根據(jù)需要決定應(yīng)調(diào)用哪個(gè)函數(shù),并用LoadLibrary和GetProcAddress動(dòng)態(tài)獲得DLL函數(shù)的入口地址。



教你認(rèn)識(shí)動(dòng)態(tài)鏈接庫DLL文件


  DLL是Dynamic Link Library的縮寫,意為動(dòng)態(tài)鏈接庫。在Windows中,許多應(yīng)用程序并不是一個(gè)完整的可執(zhí)行文件,它們被分割成一些相對(duì)獨(dú)立的動(dòng)態(tài)鏈接庫,即DLL文件,放置于系統(tǒng)中。當(dāng)我們執(zhí)行某一個(gè)程序時(shí),相應(yīng)的DLL文件就會(huì)被調(diào)用。一個(gè)應(yīng)用程序可有多個(gè)DLL文件,一個(gè)DLL文件也可能被幾個(gè)應(yīng)用程序所共用,這樣的DLL文件被稱為共享DLL文件。DLL文件一般被存放在C:WindowsSystem目錄下。


  1、如何了解某應(yīng)用程序使用哪些DLL文件

  右鍵單擊該應(yīng)用程序并選擇快捷菜單中的“快速查看”命令,在隨后出現(xiàn)的“快速查看”窗口的“引入表”一欄中你將看到其使用DLL文件的情況。

  2、如何知道DLL文件被幾個(gè)程序使用

  運(yùn)行Regedit,進(jìn)入HKEY_LOCAL_MACHINESoftwareMicrosrftWindowsCurrent-
VersionSharedDlls子鍵查看,其右邊窗口中就顯示了所有DLL文件及其相關(guān)數(shù)據(jù),其中數(shù)據(jù)右邊小括號(hào)內(nèi)的數(shù)字就說明了被幾個(gè)程序使用,(2)表示被兩個(gè)程序使用,(0)則表示無程序使用,可以將其刪除。

  3、如何解決DLL文件丟失的情況

  有時(shí)在卸載文件時(shí)會(huì)提醒你刪除某個(gè)DLL文件可能會(huì)影響其他應(yīng)用程序的運(yùn)行。所以當(dāng)你卸載軟件時(shí),就有可能誤刪共享的DLL文件。一旦出現(xiàn)了丟失DLL文件的情況,如果你能確定其名稱,可以在Sysbckup(系統(tǒng)備份文件夾)中找到該DLL文件,將其復(fù)制到System文件夾中。如果這樣不行,在電腦啟動(dòng)時(shí)又總是出現(xiàn)“***dll文件丟失……”的提示框,你可以在“開始/運(yùn)行”中運(yùn)行Msconfig,進(jìn)入系統(tǒng)配置實(shí)用程序?qū)υ捒蛞院?,單擊選擇“System.ini”標(biāo)簽,找出提示丟失的DLL文件,使其不被選中,這樣開機(jī)時(shí)就不會(huì)出現(xiàn)錯(cuò)誤提示了。


什么是DLL
DLL是一個(gè)包含可由多個(gè)程序同時(shí)使用的代碼和數(shù)據(jù)的集合。例如,在Windows操作系統(tǒng)中,Comdlg32 DLL執(zhí)行與對(duì)話框有關(guān)的常見函數(shù)。因此,每個(gè)程序都可以使用該DLL中包含的功能來實(shí)現(xiàn)“打開”對(duì)話框。這有助于促進(jìn)代碼重用和內(nèi)存的有效使用。
通過使用DLL,程序可以實(shí)現(xiàn)模塊化,由相對(duì)獨(dú)立的組件組成。例如,一個(gè)計(jì)帳程序可以按模塊來銷售??梢栽谶\(yùn)行時(shí)將各個(gè)模塊加載到主程序中(如果安裝了相應(yīng)模塊)。因?yàn)槟K是彼此獨(dú)立的,所以程序的加載速度更快,而且模塊只在相應(yīng)的功能被請(qǐng)求時(shí)才加載。

DLL的優(yōu)點(diǎn)
1. 使用較少的資源。當(dāng)多個(gè)程序使用同一個(gè)函數(shù)庫時(shí),DLL可以減少在磁盤和物理內(nèi)存中加載的代碼的重復(fù)量。這不僅可以大大影響在前臺(tái)運(yùn)行的程序,而且可以大大影響其他在Windows操作系統(tǒng)上運(yùn)行的程序。
2. 簡化部署和安裝。當(dāng)DLL中的函數(shù)需要更新或修復(fù)時(shí),只要函數(shù)的參數(shù)和返回值沒有更改,就不需重新編譯或重新建立程序與該DLL的鏈接。此外,如果多個(gè)程序使用同一個(gè)DLL,那么多個(gè)程序都將從該更新或修復(fù)中獲益。
3. 支持多語言程序。只要程序遵循函數(shù)的調(diào)用約定,用不同編程語言編寫的程序就可以調(diào)用相同的DLL函數(shù)。程序與DLL函數(shù)在下列方面必須是兼容的:函數(shù)期望其參數(shù)被推送到堆棧上的順序,是函數(shù)還是應(yīng)用程序負(fù)責(zé)清理堆棧,以及寄存器中是否傳遞了任何參數(shù)。
4. 使國際版本的創(chuàng)建輕松完成。通過將資源放到DLL中,創(chuàng)建應(yīng)用程序的國際版本變得容易得多??蓪⒂糜趹?yīng)用程序的每個(gè)語言版本的字符串放到單獨(dú)的DLL資源文件中,并使不同的語言版本加載合適的資源。

DLL的類型(Kinds of DLLs)
Visual C++支持三種類型的DLL,它們分別是Non-MFC DLL、MFC Regular DLL、MFC Extension DLL。
1. Non-MFC DLL指的是不用MFC的類庫結(jié)構(gòu),直接用C語言寫的DLL,其導(dǎo)出的函數(shù)是標(biāo)準(zhǔn)的C接口,能被MFC或非MFC編寫的客戶程序調(diào)用。
2. Extension DLL支持C++接口,也就是說它導(dǎo)出C++函數(shù)或者整個(gè)類給客戶程序。導(dǎo)出函數(shù)可以使用C++或MFC的數(shù)據(jù)形式作為參數(shù)或返回值,當(dāng)導(dǎo)出整個(gè)類時(shí),客戶程序可以創(chuàng)建此類的對(duì)象或者從這些類進(jìn)行派生。使用Extension DLL的一個(gè)問題就是該DLL僅能和MFC客戶程序一起工作。
3. Regular DLL和上述的Extension Dll一樣,也是用MFC類庫編寫的,它的一個(gè)明顯的特點(diǎn)是在源文件里有一個(gè)繼承CWinApp的類(注意:此類DLL雖然從CWinApp派生,但沒有消息循環(huán))。Regular DLL有一個(gè)很大的限制就是,它可以導(dǎo)出C風(fēng)格的函數(shù),但不能導(dǎo)出C++類、成員函數(shù)或重載函數(shù)。調(diào)用Regular DLL的客戶程序不必是MFC應(yīng)用程序。
它們可以是在Visual C++、Dephi、Visual Basic等編譯環(huán)境下開發(fā)的客戶程序。

DLL的加載
客戶程序使用DLL可以采用兩種方式:一種是隱式鏈接,另一種是顯式鏈接。
1. 隱式鏈接(靜態(tài)加載或加載時(shí)動(dòng)態(tài)鏈接)
為了隱式鏈接到DLL,客戶程序必須從DLL的提供程序獲取下列各項(xiàng):
a. 包含導(dǎo)出函數(shù)或C++類聲明的頭文件(.h文件)
b. 要鏈接的導(dǎo)入庫(.lib文件)
c. 實(shí)際的DLL(.dll文件)
使用DLL的客戶程序必須include頭文件(此頭文件包含每個(gè)DLL中的導(dǎo)出函數(shù)或C++類),并且鏈接到此DLL的創(chuàng)建者所提供的導(dǎo)入庫。
Java代碼
  1. // Cacl.cpp   
  2. ...   
  3. DLLAPI int Sum(int a, int b)   
  4. {   
  5.     return a + b;   
  6. }   
  7.   
  8. // Cacl.h   
  9. #ifdef CACL_EXPORTS   
  10. #define DLLAPI __declspec(dllexport)   
  11. #else  
  12. #define DLLAPI __declspec(dllimport)   
  13. #endif   
  14.   
  15. DLLAPI int Sum(int a, int b);   
  16.   
  17. // Client.cpp   
  18. DLLAPI int sum(int a, int b);   
  19. ...  

2. 顯式鏈接(動(dòng)態(tài)加載或運(yùn)行時(shí)動(dòng)態(tài)鏈接)
在顯式鏈接下,客戶程序必須進(jìn)行函數(shù)調(diào)用以在運(yùn)行時(shí)顯式加載DLL。為顯式鏈接到DLL,客戶程序必須:
a. 調(diào)用LoadLibrary加載DLL和獲取模塊句柄
b. 調(diào)用GetProcAddress獲取指向客戶程序要調(diào)用的每個(gè)導(dǎo)出函數(shù)的函數(shù)指針(由于客戶程序是通過指針調(diào)用DLL的函數(shù),編譯器不生成外部引用,故無需與導(dǎo)入庫鏈接)
c. 使用完DLL后調(diào)用FreeLibrary釋放資源
Java代碼
  1. // Client.cpp   
  2. HINSTANCE hDLL = LoadLibrary("demo");   
  3. if (hDLL != NULL)   
  4. {   
  5.     LPFNDLLFUNC1 lpfnDllFunc1 = GetProcAddress(hDLL, "Sum");   
  6.     if (lpfnDllFunc1 == NULL)   
  7.     {   
  8.         FreeLibrary(hDLL);   
  9.         return SOME_ERROR_CODE;   
  10.     }   
  11.     return lpfnDllFunc1(dwParam, uParam);   
  12. }  

客戶程序如何找到DLL
如果用LoadLibrary顯示鏈接到DLL的話,我們可以指定DLL的全路徑名。如果沒有指定路徑名,或者用了隱式鏈接,則Windows將使用下面的搜索序列來定位DLL:
1. 包含客戶EXE文件的目錄
2. 當(dāng)前目錄
3. Windows系統(tǒng)目錄(GetSystemDirectory)
4. Windows目錄(GetWindowsDirectory)
5. 在Path環(huán)境變量里列出的目錄(注意:未使用LIBPATH環(huán)境變量)

導(dǎo)出DLL函數(shù)
DLL文件的布局與EXE文件非常相似,但有一個(gè)重要差異:DLL文件包含導(dǎo)出表。導(dǎo)出表包含DLL導(dǎo)出到客戶程序的每個(gè)函數(shù)的名稱。只有導(dǎo)出表中的函數(shù)可由客戶程序訪問。DLL中的任何其他函數(shù)都是DLL私有的。通過使用帶/EXPORTS選項(xiàng)的Dumpbin工具,可以查看DLL的導(dǎo)出表。
有兩種從DLL導(dǎo)出函數(shù)的方法:
1. 在函數(shù)的定義中使用__declspec(dllexport)關(guān)鍵字
使用__declspec(dllexport)關(guān)鍵字可以從DLL中導(dǎo)出數(shù)據(jù)、函數(shù)、類或類成員函數(shù)。如果要導(dǎo)出函數(shù),__declspec(dllexport)關(guān)鍵字必須出現(xiàn)在調(diào)用約定關(guān)鍵字()的左邊(如果指定了關(guān)鍵字)。例如:
Java代碼
  1. __declspec(dllexport) void __cdecl Function();  


若要導(dǎo)出類中的所有公共數(shù)據(jù)成員和成員函數(shù),關(guān)鍵字必須出現(xiàn)在類名的左邊,如下所示:
Java代碼
  1. class __declspec(dllexport) CExampleExport : public CObject   
  2. {   
  3.     ...   
  4. };  

2. 在生成DLL時(shí),創(chuàng)建一個(gè)模塊定義(.def)文件并使用此DEF文件。(如果希望按序號(hào)而不是按名稱從DLL導(dǎo)出函數(shù),則使用此方法。)

示例DLL和客戶程序
Vc代碼
  1. // Cacl.h   
  2. #ifdef CACL_EXPORTS   
  3. #define DLLAPI __declspec(dllexport)   
  4. #else   
  5. #define DLLAPI __declspec(dllimport)   
  6. #endif   
  7.   
  8. DLLAPI int Sum(int a, int b);   
  9.   
  10. // Cacl.cpp   
  11. #include <windows.h>   
  12. #include "Cacl.h"  
  13.   
  14. BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)   
  15. {   
  16.     switch (reason)   
  17.     {   
  18.         case DLL_PROCESS_ATTACH:   
  19.         case DLL_THREAD_ATTACH:   
  20.         case DLL_THREAD_DETACH:   
  21.         case DLL_PROCESS_DETACH:   
  22.             break;   
  23.     }   
  24.     return TRUE;   
  25. }   
  26.   
  27. DLLAPI int Sum(int a, int b)   
  28. {   
  29.     return a + b;   
  30. }   
  31.   
  32. // Client.cpp   
  33. #include <stdio.h>   
  34. #include "Cacl.h"  
  35.   
  36. int main(int argc, char* argv[])   
  37. {   
  38.     printf("Sum = %d\n", Sum(53));   
  39.     return 0;   
  40. }  
如何調(diào)試DLL
調(diào)試DLL很容易,只要從DLL工程啟動(dòng)調(diào)試器即可。第一次這樣做的時(shí)候,調(diào)試器會(huì)請(qǐng)求給出客戶EXE程序的路徑。之后,每次從調(diào)試器運(yùn)行DLL時(shí),調(diào)試器會(huì)自動(dòng)裝入客戶EXE程序,而EXE用搜索序列找到DLL。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C/C++中動(dòng)態(tài)鏈接庫的創(chuàng)建和調(diào)用
__declspec(dllimport)的作用
在寫dll時(shí)關(guān)于declspec(dllexport)和declspec(dllimport)
__declspec(dllimport)的作用到底在哪里呢
靜態(tài)鏈接庫與動(dòng)態(tài)鏈接庫導(dǎo)出函數(shù)詳解(本文系轉(zhuǎn)載)
VC 的DLL應(yīng)用(含Demo演示) - 一點(diǎn)一滴的Beer - 博客園
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服