版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、VC+動(dòng)態(tài)鏈接庫(kù)動(dòng)態(tài)鏈接庫(kù)(DLL)編程編程1.概論概論 先來(lái)論述一下先來(lái)論述一下DLL(Dynamic Linkable Library)的概念,你可以簡(jiǎn)單的把的概念,你可以簡(jiǎn)單的把DLL看成一種倉(cāng)庫(kù),它提供給你一些可以直看成一種倉(cāng)庫(kù),它提供給你一些可以直接拿來(lái)用的變量、函數(shù)或類。接拿來(lái)用的變量、函數(shù)或類。在倉(cāng)庫(kù)的開展史上經(jīng)歷了在倉(cāng)庫(kù)的開展史上經(jīng)歷了“無(wú)庫(kù)靜態(tài)鏈無(wú)庫(kù)靜態(tài)鏈接庫(kù)動(dòng)態(tài)鏈接庫(kù)的時(shí)代。接庫(kù)動(dòng)態(tài)鏈接庫(kù)的時(shí)代。 對(duì)動(dòng)態(tài)鏈接庫(kù),需建立如下概念:對(duì)動(dòng)態(tài)鏈接庫(kù),需建立如下概念: 1與詳細(xì)的編程語(yǔ)言及編譯器無(wú)關(guān)與詳細(xì)的編程語(yǔ)言及編譯器無(wú)關(guān) 只要遵循約定的只要遵循約定的DLL接口規(guī)范和調(diào)用方接口規(guī)
2、范和調(diào)用方式,用各種語(yǔ)言編寫的式,用各種語(yǔ)言編寫的DLL都可以互相都可以互相調(diào)用。調(diào)用。譬如譬如Windows提供的系統(tǒng)提供的系統(tǒng)DLL其中包其中包括了括了Windows的的API,在任何開發(fā)環(huán)境,在任何開發(fā)環(huán)境中都能被調(diào)用,不在乎其是中都能被調(diào)用,不在乎其是Visual Basic、Visual C+還是還是Delphi。 2動(dòng)態(tài)鏈接庫(kù)隨處可見動(dòng)態(tài)鏈接庫(kù)隨處可見 在在Windows目錄下的目錄下的system32文件夾中文件夾中會(huì)看到會(huì)看到kernel32.dll、user32.dll和和gdi32.dll,windows的大多數(shù)的大多數(shù)API都包含都包含在這些在這些DLL中。中。kerne
3、l32.dll中的函數(shù)主要處置內(nèi)存管理中的函數(shù)主要處置內(nèi)存管理和進(jìn)程調(diào)度;和進(jìn)程調(diào)度;user32.dll中的函數(shù)主要控制用戶界面中的函數(shù)主要控制用戶界面(MessageBox函數(shù)函數(shù));gdi32.dll中的函數(shù)那么負(fù)責(zé)圖形方面的操中的函數(shù)那么負(fù)責(zé)圖形方面的操作。作。 (3)VC動(dòng)態(tài)鏈接庫(kù)的分類動(dòng)態(tài)鏈接庫(kù)的分類Visual C+支持三種支持三種DLL,它們分別是非,它們分別是非MFC動(dòng)動(dòng)態(tài)庫(kù)、態(tài)庫(kù)、MFC規(guī)那么規(guī)那么DLL、MFC Extension DLL。 非非MFC動(dòng)態(tài)庫(kù)不采用動(dòng)態(tài)庫(kù)不采用MFC類庫(kù)構(gòu)造,其導(dǎo)出函類庫(kù)構(gòu)造,其導(dǎo)出函數(shù)為規(guī)范的數(shù)為規(guī)范的C接口,能被非接口,能被非MFC或或
4、MFC編寫的應(yīng)編寫的應(yīng)用程序所調(diào)用;用程序所調(diào)用;MFC規(guī)那么規(guī)那么DLL 包含一個(gè)繼承自包含一個(gè)繼承自CWinApp的類,的類,但其無(wú)消息循環(huán);但其無(wú)消息循環(huán);MFC擴(kuò)展擴(kuò)展DLL采用采用MFC的動(dòng)態(tài)鏈接版本創(chuàng)建,的動(dòng)態(tài)鏈接版本創(chuàng)建,它只能被用它只能被用MFC類庫(kù)所編寫的應(yīng)用程序所調(diào)用。類庫(kù)所編寫的應(yīng)用程序所調(diào)用。 2.靜態(tài)鏈接庫(kù)靜態(tài)鏈接庫(kù) 在在VC+6.0中中new一個(gè)名稱為一個(gè)名稱為libTest的的static library工程工程,并新建并新建lib.h和和lib.cpp兩個(gè)文件,兩個(gè)文件,lib.h和和lib.cpp的源代碼的源代碼如下:如下: /文件:文件:lib.h #ifn
5、def LIB_H #define LIB_H extern C int add(int x,int y);/聲明為聲明為C編譯、連編譯、連接方式的外部函數(shù)接方式的外部函數(shù) #endif /文件:文件:lib.cpp #include lib.h int add(int x,int y) return x + y; #include #include .lib.h #pragma comment( lib, .debuglibTest.lib ) /指定與靜態(tài)庫(kù)指定與靜態(tài)庫(kù)一起連接一起連接 int main(int argc, char* argv) printf( 2 + 3 = %d, a
6、dd( 2, 3 ) ); 選擇選擇tools、options、directories、library files菜單菜單或選項(xiàng),填入庫(kù)文件途徑或選項(xiàng),填入庫(kù)文件途徑 4.非非MFC DLL 在建立的工程中添加在建立的工程中添加lib.h及及l(fā)ib.cpp文件,源代碼文件,源代碼如下:如下:/* 文件名:文件名:lib.h*/#ifndef LIB_H#define LIB_Hextern C int _declspec(dllexport)add(int x, int y);#endif/* 文件名:文件名:lib.cpp*/#include lib.hint add(int x, int
7、y)return x + y;dllCall #include #include typedef int(*lpAddFun)(int, int); /宏定義函數(shù)指針類型宏定義函數(shù)指針類型int main(int argc, char *argv) HINSTANCE hDll; /DLL句柄句柄 lpAddFun addFun; /函數(shù)指針函數(shù)指針 hDll = LoadLibrary(.DebugdllTest.dll); if (hDll != NULL) addFun = (lpAddFun)GetProcAddress(hDll, add); if (addFun != NULL)
8、int result = addFun(2, 3); printf(%d, result); FreeLibrary(hDll); return 0;DLL的調(diào)用和靜態(tài)鏈接庫(kù)的調(diào)用有較大差別的調(diào)用和靜態(tài)鏈接庫(kù)的調(diào)用有較大差別 首先,語(yǔ)句首先,語(yǔ)句typedef int ( * lpAddFun)(int,int)定義了一個(gè)與定義了一個(gè)與add函數(shù)接受參數(shù)類型和返回值均一樣的函數(shù)指針類型。隨函數(shù)接受參數(shù)類型和返回值均一樣的函數(shù)指針類型。隨后,在后,在main函數(shù)中定義了函數(shù)中定義了lpAddFun的實(shí)例的實(shí)例addFun;其次,在函數(shù)其次,在函數(shù)main中定義了一個(gè)中定義了一個(gè)DLL HINST
9、ANCE句柄實(shí)句柄實(shí)例例hDll,通過,通過Win32 Api函數(shù)函數(shù)LoadLibrary動(dòng)態(tài)加載了動(dòng)態(tài)加載了DLL模塊并將模塊并將DLL模塊句柄賦給了模塊句柄賦給了hDll;再次,在函數(shù)再次,在函數(shù)main中通過中通過Win32 Api函數(shù)函數(shù)GetProcAddress得得到了所加載到了所加載DLL模塊中函數(shù)模塊中函數(shù)add的地址并賦給了的地址并賦給了addFun。經(jīng)由函數(shù)指針經(jīng)由函數(shù)指針addFun進(jìn)展了對(duì)進(jìn)展了對(duì)DLL中中add函數(shù)的調(diào)用;函數(shù)的調(diào)用;最后,應(yīng)用工程使用完最后,應(yīng)用工程使用完DLL后,在函數(shù)后,在函數(shù)main中通過中通過Win32 Api函數(shù)函數(shù)FreeLibrary
10、釋放了已經(jīng)加載的釋放了已經(jīng)加載的DLL模塊。模塊。聲明導(dǎo)出函數(shù)聲明導(dǎo)出函數(shù) DLL中導(dǎo)出函數(shù)的聲明有兩種方式:中導(dǎo)出函數(shù)的聲明有兩種方式:一種為給出的在函數(shù)聲明中加上一種為給出的在函數(shù)聲明中加上_declspec(dllexport);一種方式是采用模塊定義一種方式是采用模塊定義(.def) 文件聲明文件聲明;在在DLL中想要中想要export的函數(shù)和數(shù)據(jù)定義的函數(shù)和數(shù)據(jù)定義前添加前添加_declspecdllexport關(guān)鍵字關(guān)鍵字對(duì)于函數(shù)和變量定義,加在最前面;對(duì)于函數(shù)和變量定義,加在最前面;對(duì)于對(duì)于class定義,加在定義,加在class關(guān)鍵字后關(guān)鍵字后;_declspec(dllexp
11、ort) void ShowDlg(void)class _declspec(dllexport) class_name /導(dǎo)導(dǎo)出類出類 這樣該函數(shù)和數(shù)據(jù)就會(huì)被添加到這樣該函數(shù)和數(shù)據(jù)就會(huì)被添加到ET中。中。使用這種方法函數(shù)將按名字使用這種方法函數(shù)將按名字export。_declspec(dllexport)(.def) 文件聲明文件聲明 為為DLL創(chuàng)建一個(gè)創(chuàng)建一個(gè).DEF文件模塊定義文件模塊定義文件,并在文件,并在build該該DLL時(shí)使用這時(shí)使用這個(gè)個(gè).DEF文件。使用這種方法使你可以文件。使用這種方法使你可以將函數(shù)按序號(hào)將函數(shù)按序號(hào)export。 在在LINK選項(xiàng)卡中假設(shè):選項(xiàng)卡中假設(shè):
12、/def:lib.def 將將lib.def參與到工程中。參與到工程中。lib.def; lib.def : 導(dǎo)出導(dǎo)出DLL函數(shù)函數(shù)LIBRARY dllTestEXPORTSadd 1.def文件的規(guī)那么為:文件的規(guī)那么為:(1)LIBRARY語(yǔ)句說明語(yǔ)句說明.def文件相應(yīng)的文件相應(yīng)的DLL;(2)EXPORTS語(yǔ)句后列出要導(dǎo)出函數(shù)的名稱。語(yǔ)句后列出要導(dǎo)出函數(shù)的名稱。可以在可以在.def文件中的導(dǎo)出函數(shù)名后加文件中的導(dǎo)出函數(shù)名后加n,表示要導(dǎo),表示要導(dǎo)出函數(shù)的序號(hào)為出函數(shù)的序號(hào)為n在進(jìn)展函數(shù)調(diào)用時(shí),這個(gè)序號(hào)在進(jìn)展函數(shù)調(diào)用時(shí),這個(gè)序號(hào)將發(fā)揮其作用;將發(fā)揮其作用;(3).def 文件中的注釋由
13、每個(gè)注釋行開場(chǎng)處的文件中的注釋由每個(gè)注釋行開場(chǎng)處的分號(hào)分號(hào) (;) 指定,且注釋不能與語(yǔ)句共享一行。指定,且注釋不能與語(yǔ)句共享一行。庫(kù)的調(diào)試與查看庫(kù)的調(diào)試與查看 動(dòng)態(tài)鏈接庫(kù)中的導(dǎo)出接口可以使用動(dòng)態(tài)鏈接庫(kù)中的導(dǎo)出接口可以使用Visual C+的的Depends工具進(jìn)展查看,工具進(jìn)展查看,用用Depends翻開系統(tǒng)目錄中的翻開系統(tǒng)目錄中的MouseHook.dll .DLL的調(diào)用方式的調(diào)用方式 隱式調(diào)用隱式調(diào)用: 將將DLL工程生成的工程生成的.lib文件和文件和.dll文件拷文件拷入當(dāng)前工程所在的目錄,并在入當(dāng)前工程所在的目錄,并在*.cpp文文件的頂部添加:件的頂部添加: #pragma co
14、mment(lib,RegularDll.lib) OR動(dòng)態(tài)調(diào)用動(dòng)態(tài)調(diào)用特點(diǎn)特點(diǎn):是完全由編程者用是完全由編程者用 API 函數(shù)加載和函數(shù)加載和卸載卸載 DLL,程序員可以決定,程序員可以決定 DLL 文件文件何時(shí)加載或不加載,顯式鏈接在運(yùn)行時(shí)何時(shí)加載或不加載,顯式鏈接在運(yùn)行時(shí)決定加載哪個(gè)決定加載哪個(gè) DLL 文件。文件。dllTest.dll 在建立的工程中添加在建立的工程中添加lib.h及及l(fā)ib.cpp文件,源代碼如下:文件,源代碼如下:/* 文件名:文件名:lib.h*/#ifndef LIB_H#define LIB_Hextern C int _declspec(dllexport
15、)add(int x, int y);#endif/* 文件名:文件名:lib.cpp*/#include lib.hint add(int x, int y)return x + y;調(diào)用調(diào)用 dllTest.dll #include #include typedef int(*lpAddFun)(int, int); /宏定義函數(shù)指針類型宏定義函數(shù)指針類型int main(int argc, char *argv) HINSTANCE hDll; /DLL句柄句柄 lpAddFun addFun; /函數(shù)指針函數(shù)指針hDll = LoadLibrary(.DebugdllTest.dll)
16、;if (hDll != NULL) addFun = (lpAddFun)GetProcAddress(hDll, add);if (addFun != NULL)int result = addFun(2, 3);printf(%d, result);FreeLibrary(hDll); DLL的的Export和和Import DLL的的export是指將是指將DLL中的函數(shù)和數(shù)據(jù)輸出中的函數(shù)和數(shù)據(jù)輸出到其它程式中,以供其使用。到其它程式中,以供其使用。DLL的的import是是指使用指使用DLL的程式引入的程式引入DLL中的函數(shù)和數(shù)據(jù)。中的函數(shù)和數(shù)據(jù)。DLL的的export DLL中包含
17、有一個(gè)表,稱為中包含有一個(gè)表,稱為export table以下簡(jiǎn)稱以下簡(jiǎn)稱ET,其中包含了,其中包含了DLL中可以被外部程式使用的所有函數(shù)和數(shù)據(jù)中可以被外部程式使用的所有函數(shù)和數(shù)據(jù)的名字。的名字。只要記錄在只要記錄在ET中的函數(shù)和數(shù)據(jù)才可以被外部中的函數(shù)和數(shù)據(jù)才可以被外部程式所使用假如沒有程式所使用假如沒有.DEF文件的話,其它文件的話,其它所有沒有記錄在所有沒有記錄在ET中的函數(shù)和數(shù)據(jù)都被視為中的函數(shù)和數(shù)據(jù)都被視為是是DLL私有的。私有的。DllMain函數(shù)函數(shù) Windows在加載在加載DLL的時(shí)候,需要一個(gè)入口函的時(shí)候,需要一個(gè)入口函數(shù),就好像控制臺(tái)或數(shù),就好像控制臺(tái)或DOS程序需要程序
18、需要main函數(shù)、函數(shù)、WIN32程序需要程序需要WinMain函數(shù)一樣。函數(shù)一樣。在前面的例子中,在前面的例子中,DLL并沒有提供并沒有提供DllMain函函數(shù),應(yīng)用工程也能勝利引用數(shù),應(yīng)用工程也能勝利引用DLL,這是因?yàn)?,這是因?yàn)閃indows在找不到在找不到DllMain的時(shí)候,系統(tǒng)會(huì)從的時(shí)候,系統(tǒng)會(huì)從其它運(yùn)行庫(kù)中引入一個(gè)不做任何操作的缺省其它運(yùn)行庫(kù)中引入一個(gè)不做任何操作的缺省DllMain函數(shù)版本,并不意味著函數(shù)版本,并不意味著DLL可以放棄可以放棄DllMain函數(shù)。函數(shù)。 BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_
19、for_call, LPVOID lpReserved) DllMain函數(shù)在函數(shù)在DLL被加載和卸載時(shí)被調(diào)用,在單個(gè)線程啟動(dòng)和終止時(shí),被加載和卸載時(shí)被調(diào)用,在單個(gè)線程啟動(dòng)和終止時(shí),DLLMain函數(shù)也被調(diào)用函數(shù)也被調(diào)用; ul_reason_for_call指明了被調(diào)用的原因。原因共有指明了被調(diào)用的原因。原因共有4種,即種,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和和THREAD_DETACH,以,以switch語(yǔ)句列出。語(yǔ)句列出。DLL導(dǎo)出變量導(dǎo)出變量 /* 文件名:文件名:lib.h*/#ifndef LIB_H#define LIB_He
20、xtern int dllGlobalVar;#endif/* 文件名:文件名:lib.cpp */#include lib.h#include int dllGlobalVar;BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) dllGlobalVar = 100; /在在dll被加載時(shí),賦全局變量為被加載時(shí),賦全局變量為100 return TRUE;文件名:文件名:lib.def;在在DLL中導(dǎo)出變量中導(dǎo)出變量LIBRARY dllTestEXPORTSdllGlobalV
21、ar DATA 在主函數(shù)中引用在主函數(shù)中引用DLL中定義的全局變量:中定義的全局變量:#include #pragma comment(lib,dllTest.lib)extern int _declspec(dllimport) dllGlobalVar; /用用_declspec(dllimport)導(dǎo)入導(dǎo)入int main(int argc, char *argv)printf(%d , dllGlobalVar);dllGlobalVar = 1; printf(%d , dllGlobalVar);return 0;特別要注意特別要注意用用extern int dllGlobalVa
22、r聲明所導(dǎo)入的并不是聲明所導(dǎo)入的并不是DLL中全局變量自身,而是其地址,應(yīng)用程序中全局變量自身,而是其地址,應(yīng)用程序必需通過強(qiáng)迫指針轉(zhuǎn)換來(lái)使用必需通過強(qiáng)迫指針轉(zhuǎn)換來(lái)使用DLL中的全局變中的全局變量。這一點(diǎn),從量。這一點(diǎn),從*(int*)dllGlobalVar可以看出??梢钥闯觥R蚨诓捎眠@種方式引用因而在采用這種方式引用DLL全局變量時(shí),千全局變量時(shí),千萬(wàn)不要進(jìn)展這樣的賦值操作:萬(wàn)不要進(jìn)展這樣的賦值操作:dllGlobalVar = 1;MFC規(guī)那么規(guī)那么DLL MFC規(guī)那么規(guī)那么DLL的概念表達(dá)在兩方面:的概念表達(dá)在兩方面:它是它是MFC的的 “是是MFC的意味著可以在這種的意味著可以在這
23、種DLL的內(nèi)部使的內(nèi)部使用用MFC;它是規(guī)那么的它是規(guī)那么的 “是規(guī)那么的意味著它不同于是規(guī)那么的意味著它不同于MFC擴(kuò)展擴(kuò)展DLL,在在MFC規(guī)那么規(guī)那么DLL的內(nèi)部雖然可以使用的內(nèi)部雖然可以使用MFC,但是其與應(yīng)用程序的接口不能是但是其與應(yīng)用程序的接口不能是MFC。而。而MFC擴(kuò)展擴(kuò)展DLL與應(yīng)用程序的接口可以是與應(yīng)用程序的接口可以是MFC,可以從可以從MFC擴(kuò)展擴(kuò)展DLL中導(dǎo)出一個(gè)中導(dǎo)出一個(gè)MFC類的派類的派生類。生類。Regular DLL可以被所有支持可以被所有支持DLL技術(shù)的語(yǔ)言技術(shù)的語(yǔ)言所編寫的應(yīng)用程序調(diào)用,當(dāng)然也包括使用所編寫的應(yīng)用程序調(diào)用,當(dāng)然也包括使用MFC的應(yīng)用程序。的應(yīng)
24、用程序。 Regular DLL分為兩類:分為兩類: 1靜態(tài)鏈接到靜態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 靜態(tài)鏈接到靜態(tài)鏈接到MFC的規(guī)那么的規(guī)那么DLL與與MFC庫(kù)包括庫(kù)包括MFC擴(kuò)展擴(kuò)展 DLL靜態(tài)鏈接,將靜態(tài)鏈接,將MFC庫(kù)的代碼直接生成在庫(kù)的代碼直接生成在.dll文件中。文件中。在調(diào)用這種在調(diào)用這種DLL的接口時(shí),的接口時(shí),MFC使用使用DLL的資源。因而,的資源。因而,在靜態(tài)鏈接到在靜態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL中不需要進(jìn)展模塊狀態(tài)的中不需要進(jìn)展模塊狀態(tài)的切換。切換。 使用這種方法生成的規(guī)那么使用這種方法生成的規(guī)那么DLL其程序較大,也可能包含反其程序較大,也可能包含反復(fù)
25、的代碼。復(fù)的代碼。 2動(dòng)態(tài)鏈接到動(dòng)態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 動(dòng)態(tài)鏈接到動(dòng)態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 可以和使用它的可執(zhí)行文件可以和使用它的可執(zhí)行文件同時(shí)動(dòng)態(tài)鏈接到同時(shí)動(dòng)態(tài)鏈接到 MFC DLL 和任何和任何MFC擴(kuò)展擴(kuò)展 DLL。在使用。在使用了了MFC共享庫(kù)的時(shí)候,默認(rèn)情況下,共享庫(kù)的時(shí)候,默認(rèn)情況下,MFC使用主應(yīng)用程序使用主應(yīng)用程序的資源句柄來(lái)加載資源模板。這樣,當(dāng)?shù)馁Y源句柄來(lái)加載資源模板。這樣,當(dāng)DLL和應(yīng)用程序中存和應(yīng)用程序中存在一樣在一樣ID的資源時(shí)即所謂的資源反復(fù)問題,系統(tǒng)可能不的資源時(shí)即所謂的資源反復(fù)問題,系統(tǒng)可能不能獲得正確的資源。因而,對(duì)于共享能獲
26、得正確的資源。因而,對(duì)于共享MFC DLL的規(guī)那么的規(guī)那么DLL,必需進(jìn)展模塊切換以使得,必需進(jìn)展模塊切換以使得MFC可以找到正確的資源可以找到正確的資源模板。模板。MFC規(guī)那么規(guī)那么DLL的創(chuàng)建的創(chuàng)建 automation自動(dòng)化技術(shù)自動(dòng)化技術(shù) 是否支持是否支持Windows Sockets 在在MFC應(yīng)用程序中應(yīng)用程序中CWinApp取代了取代了SDK程序中程序中WinMain的地位,的地位,SDK程序程序WinMain所完成的工作由所完成的工作由CWinApp的三的三個(gè)函數(shù)完成:個(gè)函數(shù)完成:virtual BOOL InitApplication( );virtual BOOL InitI
27、nstance( );virtual BOOL Run( ); /傳說中傳說中MFC程程序的序的“活水源頭活水源頭MFC規(guī)那么規(guī)那么DLL接口函數(shù)接口函數(shù) #include StdAfx.h #include DllDialog.h _declspec(dllexport) void ShowDlg(void) 或或 extern C _declspec(dllexport) void ShowDlg(void) CDllDialog dllDialog; dllDialog.DoModal(); 分析:分析: 這個(gè)接口并不使用這個(gè)接口并不使用MFC,但是在其中卻可以調(diào)用,但是在其中卻可以調(diào)用
28、MFC擴(kuò)展類擴(kuò)展類CdllDialog的函數(shù),這表達(dá)了的函數(shù),這表達(dá)了“規(guī)那么的概類。規(guī)那么的概類。 與非與非MFC DLL完全一樣,可以使用完全一樣,可以使用_declspec(dllexport)聲明聲明或在或在.def中引出的方式導(dǎo)出中引出的方式導(dǎo)出MFC規(guī)那么規(guī)那么DLL中的接口。中的接口。MFC規(guī)那么規(guī)那么DLL的調(diào)用的調(diào)用 #pragma comment(lib,RegularDll.lib)_declspec(dllexport) void ShowDlg(void)void ShowDlg(void); 或或extern C _declspec(dllexport) void
29、ShowDlg(void)extern C void ShowDlg(void); void CRegularDllCallDlg:OnCalldllButton() ShowDlg();MFC擴(kuò)展擴(kuò)展 DLL MFC擴(kuò)展擴(kuò)展DLL與與MFC規(guī)那么規(guī)那么DLL的一樣點(diǎn)在于在兩種的一樣點(diǎn)在于在兩種DLL的內(nèi)部都可以使用的內(nèi)部都可以使用MFC類庫(kù),其不同點(diǎn)在于類庫(kù),其不同點(diǎn)在于MFC擴(kuò)展擴(kuò)展DLL與應(yīng)用程序的接口可以是與應(yīng)用程序的接口可以是MFC的。的。 MFC擴(kuò)展擴(kuò)展DLL的含義在于它是的含義在于它是MFC的擴(kuò)展,其主要功的擴(kuò)展,其主要功能是實(shí)現(xiàn)從現(xiàn)有能是實(shí)現(xiàn)從現(xiàn)有MFC庫(kù)類中派生出可重用的類。
30、庫(kù)類中派生出可重用的類。 MFC擴(kuò)展擴(kuò)展DLL使用使用MFC 動(dòng)態(tài)鏈接庫(kù)版本,因而只要?jiǎng)討B(tài)鏈接庫(kù)版本,因而只要用共享用共享MFC 版本生成的版本生成的MFC 可執(zhí)行文件應(yīng)用程序可執(zhí)行文件應(yīng)用程序或規(guī)那么或規(guī)那么DLL才干使用才干使用MFC擴(kuò)展擴(kuò)展DLL。 一般使用一般使用MFC擴(kuò)展擴(kuò)展DLL來(lái)包含一些來(lái)包含一些MFC的加強(qiáng)功能,的加強(qiáng)功能,譬如擴(kuò)展譬如擴(kuò)展MFC的的CStatic、CButton等類使之具備更強(qiáng)等類使之具備更強(qiáng)大的才干。大的才干。三種三種DLL對(duì)對(duì)DllMain入口函數(shù)的不同處置方式:入口函數(shù)的不同處置方式: DLLDLL類型類型 入口函數(shù)入口函數(shù) 非非 MFC DLL MFC
31、 DLL 編程者提供編程者提供DllMainDllMain函數(shù)函數(shù) MFCMFC規(guī)則規(guī)則 DLL DLL CWinAppCWinApp對(duì)象的對(duì)象的InitInstance InitInstance 和和 ExitInstance ExitInstance MFCMFC擴(kuò)展擴(kuò)展 DLL DLL MFC DLLMFC DLL向?qū)上驅(qū)蒁llMain DllMain 函數(shù)函數(shù) 宏宏宏為宏為DLL和應(yīng)用程序的編寫提供了方便。像和應(yīng)用程序的編寫提供了方便。像AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA在在DLL和應(yīng)用程序中將具有不同的定義,這取和應(yīng)用程序中將具有不同
32、的定義,這取決于決于_AFXEXT宏是否被定義。這使得在宏是否被定義。這使得在DLL和應(yīng)用程序中,使用統(tǒng)一的一個(gè)宏就可以表示和應(yīng)用程序中,使用統(tǒng)一的一個(gè)宏就可以表示出輸出和輸入的不同意思。出輸出和輸入的不同意思。在在DLL中,表示輸出因?yàn)橹?,表示輸出因?yàn)開AFXEXT被定義,被定義,通常是在編譯器的標(biāo)識(shí)參數(shù)中指定通常是在編譯器的標(biāo)識(shí)參數(shù)中指定/D_AFXEXT;在應(yīng)用程序中,那么表示輸入在應(yīng)用程序中,那么表示輸入_AFXEXT沒沒有定義。有定義。 AFX_CLASS_IMPORT _declspec(dllexport) AFX_API_IMPORT _declspec(dllexport)
33、AFX_DATA_IMPORT _declspec(dllexport) AFX_CLASS_EXPORT _declspec(dllexport) AFX_API_EXPORT _declspec(dllexport) AFX_DATA_EXPORT _declspec(dllexport) AFX_EXT_CLASS #ifdef _AFXEXT AFX_CLASS_EXPORT #else AFX_CLASS_IMPORT AFX_EXT_API #ifdef _AFXEXT AFX_API_EXPORT #else AFX_API_IMPORT AFX_EXT_DATA #ifdef
34、_AFXEXT AFX_DATA_EXPORT #else AFX_DATA_IMPORT class AFX_EXT_CLASS CExtDialog : public CDialog * #include .ExtDialog.h #pragma comment( lib, ExtDll.lib ) 而而“調(diào)用調(diào)用DLL按鈕的單擊事件的消息處置函數(shù)為:按鈕的單擊事件的消息處置函數(shù)為: void CLoadExtDllDlg:OnDllcallButton() CExtDialog extDialog; extDialog.DoModal(); Win32系統(tǒng)鉤子技術(shù)系統(tǒng)鉤子技術(shù)APIHOO
35、K技術(shù)應(yīng)用廣泛,常用于屏幕技術(shù)應(yīng)用廣泛,常用于屏幕取詞、網(wǎng)絡(luò)防火墻、病毒木馬、加殼軟取詞、網(wǎng)絡(luò)防火墻、病毒木馬、加殼軟件、串口紅外通信、游戲外掛、件、串口紅外通信、游戲外掛、Internet通信等領(lǐng)域。通信等領(lǐng)域。HOOK的中文意思就是鉤子,的中文意思就是鉤子,APIHOOK就是鉤住就是鉤住API,對(duì),對(duì)API進(jìn)展預(yù)進(jìn)展預(yù)處置,先執(zhí)行我們的函數(shù)。處置,先執(zhí)行我們的函數(shù)。 APIHOOK技術(shù)技術(shù)鉤子的實(shí)質(zhì)是一段用以處置系統(tǒng)消息的程序,鉤子的實(shí)質(zhì)是一段用以處置系統(tǒng)消息的程序,通過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。通過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。鉤子的品種很多,每種鉤子可以截獲并處置相鉤子的品種很多,每種鉤子可以
36、截獲并處置相應(yīng)的消息,每當(dāng)特定的消息發(fā)出,在到達(dá)目的應(yīng)的消息,每當(dāng)特定的消息發(fā)出,在到達(dá)目的窗口之前,鉤子程序先行截獲該消息、得到對(duì)窗口之前,鉤子程序先行截獲該消息、得到對(duì)此消息的控制權(quán)。此時(shí)鉤子函數(shù)可以對(duì)截獲的此消息的控制權(quán)。此時(shí)鉤子函數(shù)可以對(duì)截獲的消息進(jìn)展加工處置,甚至可以強(qiáng)迫完畢消息的消息進(jìn)展加工處置,甚至可以強(qiáng)迫完畢消息的傳送。傳送。這有點(diǎn)類似與這有點(diǎn)類似與MFC中的中的PreTranslateMessage函數(shù),所不同的是該函數(shù)只能用于攔截本進(jìn)程函數(shù),所不同的是該函數(shù)只能用于攔截本進(jìn)程中的消息,而對(duì)系統(tǒng)消息那么無(wú)能為力。中的消息,而對(duì)系統(tǒng)消息那么無(wú)能為力。 Win32系統(tǒng)鉤子的實(shí)現(xiàn)系
37、統(tǒng)鉤子的實(shí)現(xiàn) 每品種型的鉤子均由系統(tǒng)來(lái)維護(hù)一個(gè)鉤每品種型的鉤子均由系統(tǒng)來(lái)維護(hù)一個(gè)鉤子鏈,最近裝置的鉤子位于鏈的開場(chǎng),子鏈,最近裝置的鉤子位于鏈的開場(chǎng),擁有最高的優(yōu)先級(jí),而最先裝置的鉤子擁有最高的優(yōu)先級(jí),而最先裝置的鉤子那么處在鏈的末尾。那么處在鏈的末尾。要實(shí)現(xiàn)要實(shí)現(xiàn)Win32的系統(tǒng)鉤子,首先要調(diào)用的系統(tǒng)鉤子,首先要調(diào)用SDK中的中的API函數(shù)函數(shù)SetWindowsHookEx來(lái)來(lái)裝置這個(gè)鉤子函數(shù),其原型是:裝置這個(gè)鉤子函數(shù),其原型是: HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThrea
38、dId); 其中:其中: 第一個(gè)參數(shù)是鉤子的類型,常用的有第一個(gè)參數(shù)是鉤子的類型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等;等; 第二個(gè)參數(shù)是鉤子函數(shù)的地址,當(dāng)鉤子鉤到任何消息后第二個(gè)參數(shù)是鉤子函數(shù)的地址,當(dāng)鉤子鉤到任何消息后便調(diào)用這個(gè)函數(shù);便調(diào)用這個(gè)函數(shù); 第三個(gè)參數(shù)是鉤子函數(shù)所在模塊的句柄;第三個(gè)參數(shù)是鉤子函數(shù)所在模塊的句柄; 第四個(gè)參數(shù)是鉤子相關(guān)函數(shù)的第四個(gè)參數(shù)是鉤子相關(guān)函數(shù)的ID用以指定想讓鉤子去鉤用以指定想讓鉤子去鉤哪個(gè)線程,為哪個(gè)線程,為0時(shí)那么攔截整個(gè)系統(tǒng)的消息此時(shí)為全局鉤時(shí)那么攔截整個(gè)系統(tǒng)的消息此時(shí)為全局鉤子。假如指定確定的線程,即為線程專
39、用鉤子。子。假如指定確定的線程,即為線程專用鉤子。 全局鉤子函數(shù)必需包含在全局鉤子函數(shù)必需包含在DLL動(dòng)態(tài)鏈動(dòng)態(tài)鏈接庫(kù)中,而線程專用鉤子那么可包含接庫(kù)中,而線程專用鉤子那么可包含在可執(zhí)行文件中。在可執(zhí)行文件中。得到控制權(quán)的鉤子函數(shù)在處置完消息后,得到控制權(quán)的鉤子函數(shù)在處置完消息后,可以調(diào)用另外一個(gè)可以調(diào)用另外一個(gè)SDK中的中的API函數(shù)函數(shù)CallNextHookEx來(lái)繼續(xù)傳送該消息。也來(lái)繼續(xù)傳送該消息。也可以通過直接返回可以通過直接返回TRUE來(lái)丟棄該消息,來(lái)丟棄該消息,阻止該消息的傳送。阻止該消息的傳送。使用全局鉤子函數(shù)時(shí)需要以使用全局鉤子函數(shù)時(shí)需要以DLL為載體,為載體,VC6中有三種形
40、式的中有三種形式的MFC DLL可供選擇,即規(guī)范可供選擇,即規(guī)范靜態(tài)鏈接靜態(tài)鏈接MFC DLL、規(guī)范動(dòng)態(tài)鏈接、規(guī)范動(dòng)態(tài)鏈接MFC DLL以及擴(kuò)展以及擴(kuò)展MFC DLL。第一種第一種DLL在編譯時(shí)把使用的在編譯時(shí)把使用的MFC代碼鏈接代碼鏈接到到DLL中,執(zhí)行程序時(shí)不需要其他中,執(zhí)行程序時(shí)不需要其他MFC動(dòng)態(tài)動(dòng)態(tài)鏈接類庫(kù)的支持,但體積較大;鏈接類庫(kù)的支持,但體積較大;第二種第二種DLL在運(yùn)行時(shí)動(dòng)態(tài)鏈接到在運(yùn)行時(shí)動(dòng)態(tài)鏈接到MFC類庫(kù),類庫(kù),因而體積較小,但卻依賴于因而體積較小,但卻依賴于MFC動(dòng)態(tài)鏈接類庫(kù)動(dòng)態(tài)鏈接類庫(kù)的支持;這兩種的支持;這兩種DLL均可被均可被MFC程序和程序和Win32程序使用
41、。程序使用。第三種第三種DLL的也是動(dòng)態(tài)連接,但做為的也是動(dòng)態(tài)連接,但做為MFC類類庫(kù)的擴(kuò)展,只能被庫(kù)的擴(kuò)展,只能被MFC程序使用。程序使用。 Win32 DLL BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中:其中:第一個(gè)參數(shù)表示第一個(gè)參數(shù)表示DLL的實(shí)例句柄;的實(shí)例句柄;第三個(gè)參數(shù)系統(tǒng)保管;第三個(gè)參數(shù)系統(tǒng)保管;第二個(gè)參數(shù)指明了當(dāng)前調(diào)用該動(dòng)態(tài)連接庫(kù)的狀態(tài),第二個(gè)參數(shù)指明了當(dāng)前調(diào)用該動(dòng)態(tài)連接庫(kù)的狀態(tài),它有四個(gè)可能的值:它有四個(gè)可能的值:DLL_PROCESS_ATTACH進(jìn)程載入、進(jìn)程
42、載入、DLL_THREAD_ATTACH線程載入、線程載入、DLL_THREAD_DETACH線程卸載、線程卸載、DLL_PROCESS_DETACH進(jìn)程卸載。進(jìn)程卸載。DLL的共享問題的共享問題 由于在由于在Win32環(huán)境下,所有進(jìn)程的空間都是互相獨(dú)立環(huán)境下,所有進(jìn)程的空間都是互相獨(dú)立的,這減少了應(yīng)用程序間的互相影響,但大大增加了的,這減少了應(yīng)用程序間的互相影響,但大大增加了編程的難度。編程的難度。 當(dāng)進(jìn)程在動(dòng)態(tài)加載當(dāng)進(jìn)程在動(dòng)態(tài)加載DLL時(shí),系統(tǒng)自動(dòng)把時(shí),系統(tǒng)自動(dòng)把DLL地址映射地址映射到該進(jìn)程的私有空間到該進(jìn)程的私有空間; 而且也復(fù)制該而且也復(fù)制該DLL的全局?jǐn)?shù)據(jù)的一份拷貝到該進(jìn)程空的全局
43、數(shù)據(jù)的一份拷貝到該進(jìn)程空間,每個(gè)進(jìn)程所擁有的一樣的間,每個(gè)進(jìn)程所擁有的一樣的DLL的全局?jǐn)?shù)據(jù)其值卻的全局?jǐn)?shù)據(jù)其值卻并不一定是一樣的。并不一定是一樣的。 當(dāng)當(dāng)DLL內(nèi)存被映射到進(jìn)程空間中,每個(gè)進(jìn)程都有自己內(nèi)存被映射到進(jìn)程空間中,每個(gè)進(jìn)程都有自己的全局內(nèi)存拷貝,加載的全局內(nèi)存拷貝,加載DLL的每一個(gè)新的進(jìn)程都重新的每一個(gè)新的進(jìn)程都重新初始化這一內(nèi)存區(qū)域,也就是說進(jìn)程不能再共享初始化這一內(nèi)存區(qū)域,也就是說進(jìn)程不能再共享DLL。全局共享數(shù)據(jù)的實(shí)現(xiàn)全局共享數(shù)據(jù)的實(shí)現(xiàn) 在在Win32環(huán)境下要想在多個(gè)進(jìn)程中共享環(huán)境下要想在多個(gè)進(jìn)程中共享數(shù)據(jù),就必需進(jìn)展必要的設(shè)置。數(shù)據(jù),就必需進(jìn)展必要的設(shè)置。一種方法便是把這
44、些需要共享的數(shù)據(jù)單一種方法便是把這些需要共享的數(shù)據(jù)單獨(dú)分別出來(lái),放置在一個(gè)獨(dú)立的數(shù)據(jù)段獨(dú)分別出來(lái),放置在一個(gè)獨(dú)立的數(shù)據(jù)段里,并把該段的屬性設(shè)置為共享,建立里,并把該段的屬性設(shè)置為共享,建立一個(gè)內(nèi)存共享的一個(gè)內(nèi)存共享的DLL。 #pragma data_seg用用#pragma data_seg建立一個(gè)新的數(shù)據(jù)段并定義建立一個(gè)新的數(shù)據(jù)段并定義共享數(shù)據(jù),其詳細(xì)格式為:共享數(shù)據(jù),其詳細(xì)格式為: #pragma data_seg shareddata) HWND sharedwnd=NULL;/共享數(shù)據(jù)共享數(shù)據(jù) #pragma data_seg() 所有在所有在data_seg pragmas語(yǔ)句之間聲明的變量都語(yǔ)句之間聲明的變量都將在將在shareddata段中。僅定義一個(gè)數(shù)據(jù)段還不能段中。僅定義一個(gè)數(shù)據(jù)段還不能到達(dá)共享數(shù)據(jù)的目的,還要告訴編譯器該段的屬到達(dá)共享數(shù)據(jù)的目的,還要告訴編譯器該段的屬性,有兩種方法可
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司試用期轉(zhuǎn)正工作總結(jié)15篇
- 2021教師辭職報(bào)告(集錦15篇)
- 關(guān)于小學(xué)生祖國(guó)在我心中演講稿范文合集七篇
- 2024-2025學(xué)年高中語(yǔ)文 第三單元 古代議論性散文 序列寫作3善待生命 學(xué)習(xí)論證教學(xué)實(shí)錄 新人教版必修3
- 關(guān)于外貿(mào)類實(shí)習(xí)報(bào)告集錦五篇
- 八年級(jí)語(yǔ)文上冊(cè) 龜雖壽教學(xué)實(shí)錄 新人教版
- 江蘇省淮安市重點(diǎn)高中2025屆高三上學(xué)期12月階段性檢測(cè)生物試卷含答案
- 數(shù)字化背景下保險(xiǎn)法概論“雙線”教學(xué)模式的設(shè)計(jì)與實(shí)施
- 銀行對(duì)公業(yè)務(wù)主要產(chǎn)品介紹
- 簡(jiǎn)單的暑假讀書心得作文100字10篇
- DL-T5440-2020重覆冰架空輸電線路設(shè)計(jì)技術(shù)規(guī)程
- 膿毒血癥教學(xué)查房
- 行政復(fù)議法-形考作業(yè)3-國(guó)開(ZJ)-參考資料
- 工程設(shè)計(jì)能力提升措施方案
- 研究方法與學(xué)術(shù)寫作智慧樹知到期末考試答案2024年
- 柜式七氟丙烷氣體滅火系統(tǒng)安裝與綜合項(xiàng)目施工專項(xiàng)方案
- (正式版)JBT 14587-2024 膠體鉛酸蓄電池 技術(shù)規(guī)范
- 小學(xué)生作文方格紙
- 小區(qū)內(nèi)命案防控應(yīng)急預(yù)案
- 2024年內(nèi)蒙古交通集團(tuán)興安分公司招聘筆試參考題庫(kù)附帶答案詳解
- 臨電施工方案與施工組織設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論