




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、VC+動態(tài)鏈接庫動態(tài)鏈接庫(DLL)編程編程1.概論概論 先來論述一下先來論述一下DLL(Dynamic Linkable Library)的概念,他可以簡單的把的概念,他可以簡單的把DLL看成一種倉庫,它提供應(yīng)他一些可以直看成一種倉庫,它提供應(yīng)他一些可以直接拿來用的變量、函數(shù)或類。接拿來用的變量、函數(shù)或類。在倉庫的開展史上閱歷了在倉庫的開展史上閱歷了“無庫靜態(tài)鏈無庫靜態(tài)鏈接庫動態(tài)鏈接庫的時代。接庫動態(tài)鏈接庫的時代。 對動態(tài)鏈接庫,需建立如下概念:對動態(tài)鏈接庫,需建立如下概念: 1與詳細(xì)的編程言語及編譯器無關(guān)與詳細(xì)的編程言語及編譯器無關(guān) 只需遵照商定的只需遵照商定的DLL接口規(guī)范和調(diào)用方接口規(guī)
2、范和調(diào)用方式,用各種言語編寫的式,用各種言語編寫的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動態(tài)鏈接庫隨處可見動態(tài)鏈接庫隨處可見 在在Windows目錄下的目錄下的system32文件夾中文件夾中會看到會看到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ù)那么擔(dān)任圖形方面的操中的函數(shù)那么擔(dān)任圖形方面的操作。作。 (3)VC動態(tài)鏈接庫的分類動態(tài)鏈接庫的分類Visual C+支持三種支持三種DLL,它們分別是非,它們分別是非MFC動動態(tài)庫、態(tài)庫、MFC規(guī)那么規(guī)那么DLL、MFC Extension DLL。 非非MFC動態(tài)庫不采用動態(tài)庫不采用MFC類庫構(gòu)造,其導(dǎo)出函類庫構(gòu)造,其導(dǎo)出函數(shù)為規(guī)范的數(shù)為規(guī)范的C接口,能被非接口,能被非MFC或或
4、MFC編寫的運編寫的運用程序所調(diào)用;用程序所調(diào)用;MFC規(guī)那么規(guī)那么DLL 包含一個承繼自包含一個承繼自CWinApp的類,的類,但其無音訊循環(huán);但其無音訊循環(huán);MFC擴展擴展DLL采用采用MFC的動態(tài)鏈接版本創(chuàng)建,的動態(tài)鏈接版本創(chuàng)建,它只能被用它只能被用MFC類庫所編寫的運用程序所調(diào)用。類庫所編寫的運用程序所調(diào)用。 2.靜態(tài)鏈接庫靜態(tài)鏈接庫 在在VC+6.0中中new一個稱號為一個稱號為libTest的的static library工程工程,并新建并新建lib.h和和lib.cpp兩個文件,兩個文件,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)庫指定與靜態(tài)庫一同銜接一同銜接 int main(int argc, char* argv) printf( 2 + 3 = %d, a
6、dd( 2, 3 ) ); 選擇選擇tools、options、directories、library files菜單菜單或選項,填入庫文件途徑或選項,填入庫文件途徑 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)鏈接庫的調(diào)用有較大差別的調(diào)用和靜態(tài)鏈接庫的調(diào)用有較大差別 首先,語句首先,語句typedef int ( * lpAddFun)(int,int)定義了一個與定義了一個與add函數(shù)接受參數(shù)類型和前往值均一樣的函數(shù)指針類型。隨函數(shù)接受參數(shù)類型和前往值均一樣的函數(shù)指針類型。隨后,在后,在main函數(shù)中定義了函數(shù)中定義了lpAddFun的實例的實例addFun;其次,在函數(shù)其次,在函數(shù)main中定義了一個中定義了一個DLL HINST
9、ANCE句柄實句柄實例例hDll,經(jīng)過,經(jīng)過Win32 Api函數(shù)函數(shù)LoadLibrary動態(tài)加載了動態(tài)加載了DLL模塊并將模塊并將DLL模塊句柄賦給了模塊句柄賦給了hDll;再次,在函數(shù)再次,在函數(shù)main中經(jīng)過中經(jīng)過Win32 Api函數(shù)函數(shù)GetProcAddress得得到了所加載到了所加載DLL模塊中函數(shù)模塊中函數(shù)add的地址并賦給了的地址并賦給了addFun。經(jīng)由函數(shù)指針經(jīng)由函數(shù)指針addFun進(jìn)展了對進(jìn)展了對DLL中中add函數(shù)的調(diào)用;函數(shù)的調(diào)用;最后,運用工程運用完最后,運用工程運用完DLL后,在函數(shù)后,在函數(shù)main中經(jīng)過中經(jīng)過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)鍵字對于函數(shù)和變量定義,加在最前面;對于函數(shù)和變量定義,加在最前面;對于對于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ù)就會被添加到這樣該函數(shù)和數(shù)據(jù)就會被添加到ET中。中。運用這種方法函數(shù)將按名字運用這種方法函數(shù)將按名字export。_declspec(dllexport)(.def) 文件聲明文件聲明 為為DLL創(chuàng)建一個創(chuàng)建一個.DEF文件模塊定義文件模塊定義文件,并在文件,并在build該該DLL時運用這時運用這個個.DEF文件。運用這種方法使他可以文件。運用這種方法使他可以將函數(shù)按序號將函數(shù)按序號export。 在在LINK選項卡中假設(shè):選項卡中假設(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語句闡明語句闡明.def文件相應(yīng)的文件相應(yīng)的DLL;(2)EXPORTS語句后列出要導(dǎo)出函數(shù)的稱號。語句后列出要導(dǎo)出函數(shù)的稱號??梢栽诳梢栽?def文件中的導(dǎo)出函數(shù)名后加文件中的導(dǎo)出函數(shù)名后加n,表示要,表示要導(dǎo)出函數(shù)的序號為導(dǎo)出函數(shù)的序號為n在進(jìn)展函數(shù)調(diào)用時,這個序在進(jìn)展函數(shù)調(diào)用時,這個序號將發(fā)揚其作用;號將發(fā)揚其作用;(3).def 文件中的注釋由
13、每個注釋行開場處的文件中的注釋由每個注釋行開場處的分號分號 (;) 指定,且注釋不能與語句共享一行。指定,且注釋不能與語句共享一行。庫的調(diào)試與查看庫的調(diào)試與查看 動態(tài)鏈接庫中的導(dǎo)出接口可以運用動態(tài)鏈接庫中的導(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動態(tài)調(diào)用動態(tài)調(diào)用特點特點:是完全由編程者用是完全由編程者用 API 函數(shù)加載和函數(shù)加載和卸載卸載 DLL,程序員可以決議,程序員可以決議 DLL 文件文件何時加載或不加載,顯式鏈接在運轉(zhuǎn)時何時加載或不加載,顯式鏈接在運轉(zhuǎn)時決議加載哪個決議加載哪個 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、有一個表,稱為中包含有一個表,稱為export table以下簡稱以下簡稱ET,其中包含了,其中包含了DLL中可以被外部程式運用的一切函數(shù)和數(shù)據(jù)中可以被外部程式運用的一切函數(shù)和數(shù)據(jù)的名字。的名字。只需記錄在只需記錄在ET中的函數(shù)和數(shù)據(jù)才可以被外部中的函數(shù)和數(shù)據(jù)才可以被外部程式所運用假設(shè)沒有程式所運用假設(shè)沒有.DEF文件的話,其它文件的話,其它一切沒有記錄在一切沒有記錄在ET中的函數(shù)和數(shù)據(jù)都被視為中的函數(shù)和數(shù)據(jù)都被視為是是DLL私有的。私有的。DllMain函數(shù)函數(shù) Windows在加載在加載DLL的時候,需求一個入口函的時候,需求一個入口函數(shù),就好像控制臺或數(shù),就好像控制臺或DOS程序需求程序
18、需求main函數(shù)、函數(shù)、WIN32程序需求程序需求WinMain函數(shù)一樣。函數(shù)一樣。在前面的例子中,在前面的例子中,DLL并沒有提供并沒有提供DllMain函函數(shù),運用工程也能勝利援用數(shù),運用工程也能勝利援用DLL,這是由于,這是由于Windows在找不到在找不到DllMain的時候,系統(tǒng)會從的時候,系統(tǒng)會從其它運轉(zhuǎn)庫中引入一個不做任何操作的缺省其它運轉(zhuǎn)庫中引入一個不做任何操作的缺省DllMain函數(shù)版本,并不意味著函數(shù)版本,并不意味著DLL可以放棄可以放棄DllMain函數(shù)。函數(shù)。 BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_
19、for_call, LPVOID lpReserved) DllMain函數(shù)在函數(shù)在DLL被加載和卸載時被調(diào)用,在單個線程啟動和終止時,被加載和卸載時被調(diào)用,在單個線程啟動和終止時,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語句列出。語句列出。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被加載時,賦全局變量為被加載時,賦全局變量為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中全局變量本身,而是其地址,運用程序中全局變量本身,而是其地址,運用程序必需經(jīng)過強迫指針轉(zhuǎn)換來運用必需經(jīng)過強迫指針轉(zhuǎn)換來運用DLL中的全局變中的全局變量。這一點,從量。這一點,從*(int*)dllGlobalVar可以看出??梢钥闯?。因此在采用這種方式援用因此在采用這種方式援用DLL全局變量時,千全局變量時,千萬不要進(jì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擴展擴展DLL,在在MFC規(guī)那么規(guī)那么DLL的內(nèi)部雖然可以運用的內(nèi)部雖然可以運用MFC,但是其與運用程序的接口不能是但是其與運用程序的接口不能是MFC。而。而MFC擴展擴展DLL與運用程序的接口可以是與運用程序的接口可以是MFC,可以從可以從MFC擴展擴展DLL中導(dǎo)出一個中導(dǎo)出一個MFC類的派類的派生類。生類。Regular DLL可以被一切支持可以被一切支持DLL技術(shù)的言語技術(shù)的言語所編寫的運用程序調(diào)用,當(dāng)然也包括運用所編寫的運用程序調(diào)用,當(dāng)然也包括運用MFC的運用程序。的運
24、用程序。 Regular DLL分為兩類:分為兩類: 1靜態(tài)鏈接到靜態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 靜態(tài)鏈接到靜態(tài)鏈接到MFC的規(guī)那么的規(guī)那么DLL與與MFC庫包括庫包括MFC擴展擴展 DLL靜態(tài)鏈接,將靜態(tài)鏈接,將MFC庫的代碼直接生成在庫的代碼直接生成在.dll文件中。文件中。在調(diào)用這種在調(diào)用這種DLL的接口時,的接口時,MFC運用運用DLL的資源。因此,的資源。因此,在靜態(tài)鏈接到在靜態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL中不需求進(jìn)展模塊形狀的中不需求進(jìn)展模塊形狀的切換。切換。 運用這種方法生成的規(guī)那么運用這種方法生成的規(guī)那么DLL其程序較大,也能夠包含反其程序較大,也能夠包含反復(fù)
25、的代碼。復(fù)的代碼。 2動態(tài)鏈接到動態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 動態(tài)鏈接到動態(tài)鏈接到MFC 的規(guī)那么的規(guī)那么DLL 可以和運用它的可執(zhí)行文件可以和運用它的可執(zhí)行文件同時動態(tài)鏈接到同時動態(tài)鏈接到 MFC DLL 和任何和任何MFC擴展擴展 DLL。在運用。在運用了了MFC共享庫的時候,默許情況下,共享庫的時候,默許情況下,MFC運用主運用程序運用主運用程序的資源句柄來加載資源模板。這樣,當(dāng)?shù)馁Y源句柄來加載資源模板。這樣,當(dāng)DLL和運用程序中存和運用程序中存在一樣在一樣ID的資源時即所謂的資源反復(fù)問題,系統(tǒng)能夠不的資源時即所謂的資源反復(fù)問題,系統(tǒng)能夠不能獲得正確的資源。因此,對于共享能獲
26、得正確的資源。因此,對于共享MFC DLL的規(guī)那么的規(guī)那么DLL,必需進(jìn)展模塊切換以使得,必需進(jìn)展模塊切換以使得MFC可以找到正確的資源可以找到正確的資源模板。模板。MFC規(guī)那么規(guī)那么DLL的創(chuàng)建的創(chuàng)建 automation自動化技術(shù)自動化技術(shù) 能否支持能否支持Windows Sockets 在在MFC運用程序中運用程序中CWinApp取代了取代了SDK程序中程序中WinMain的位置,的位置,SDK程序程序WinMain所完成的任務(wù)由所完成的任務(wù)由CWinApp的三的三個函數(shù)完成:個函數(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(); 分析:分析: 這個接口并不運用這個接口并不運用MFC,但是在其中卻可以調(diào)用,但是在其中卻可以調(diào)用
28、MFC擴展類擴展類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擴展擴展 DLL MFC擴展擴展DLL與與MFC規(guī)那么規(guī)那么DLL的一樣點在于在兩種的一樣點在于在兩種DLL的內(nèi)部都可以運用的內(nèi)部都可以運用MFC類庫,其不同點在于類庫,其不同點在于MFC擴展擴展DLL與運用程序的接口可以是與運用程序的接口可以是MFC的。的。 MFC擴展擴展DLL的含義在于它是的含義在于它是MFC的擴展,其主要功的擴展,其主要功能是實現(xiàn)從現(xiàn)有能是實現(xiàn)從現(xiàn)有MFC庫類中派生出可重用的類。
30、庫類中派生出可重用的類。 MFC擴展擴展DLL運用運用MFC 動態(tài)鏈接庫版本,因此只需動態(tài)鏈接庫版本,因此只需用共享用共享MFC 版本生成的版本生成的MFC 可執(zhí)行文件運用程序可執(zhí)行文件運用程序或規(guī)那么或規(guī)那么DLL才干運用才干運用MFC擴展擴展DLL。 普通運用普通運用MFC擴展擴展DLL來包含一些來包含一些MFC的加強功能,的加強功能,譬如擴展譬如擴展MFC的的CStatic、CButton等類使之具備更強等類使之具備更強大的才干。大的才干。三種三種DLL對對DllMain入口函數(shù)的不同處置方式:入口函數(shù)的不同處置方式: DLL類型類型 入口函數(shù)入口函數(shù) 非非 MFC DLL MFC DL
31、L 編程者提供編程者提供DllMainDllMain函數(shù)函數(shù) MFCMFC規(guī)那么規(guī)那么 DLL DLL CWinAppCWinApp對象的對象的InitInstance InitInstance 和和 ExitInstance ExitInstance MFCMFC擴展擴展 DLL DLL MFC DLLMFC DLL導(dǎo)游生成導(dǎo)游生成DllMain DllMain 函數(shù)函數(shù) 宏宏宏為宏為DLL和運用程序的編寫提供了方便。像和運用程序的編寫提供了方便。像AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA在在DLL和運用程序中將具有不同的定義,這取和運用程序中將具有不同的
32、定義,這取決于決于_AFXEXT宏能否被定義。這使得在宏能否被定義。這使得在DLL和運用程序中,運用一致的一個宏就可以表示和運用程序中,運用一致的一個宏就可以表示出輸出和輸入的不贊同思。出輸出和輸入的不贊同思。在在DLL中,表示輸出由于中,表示輸出由于_AFXEXT被定義,被定義,通常是在編譯器的標(biāo)識參數(shù)中指定通常是在編譯器的標(biāo)識參數(shù)中指定/D_AFXEXT;在運用程序中,那么表示輸入在運用程序中,那么表示輸入_AFXEXT沒沒有定義。有定義。 AFX_CLASS_IMPORT _declspec(dllexport) AFX_API_IMPORT _declspec(dllexport) A
33、FX_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ù)APIHOOK
35、技術(shù)運用廣泛,常用于屏幕技術(shù)運用廣泛,常用于屏幕取詞、網(wǎng)絡(luò)防火墻、病毒木馬、加殼軟取詞、網(wǎng)絡(luò)防火墻、病毒木馬、加殼軟件、串口紅外通訊、游戲外掛、件、串口紅外通訊、游戲外掛、Internet通訊等領(lǐng)域。通訊等領(lǐng)域。HOOK的中文意思就是鉤子,的中文意思就是鉤子,APIHOOK就是鉤住就是鉤住API,對,對API進(jìn)展預(yù)進(jìn)展預(yù)處置,先執(zhí)行我們的函數(shù)。處置,先執(zhí)行我們的函數(shù)。 APIHOOK技術(shù)技術(shù)鉤子的本質(zhì)是一段用以處置系統(tǒng)音訊的程序,鉤子的本質(zhì)是一段用以處置系統(tǒng)音訊的程序,經(jīng)過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。經(jīng)過系統(tǒng)調(diào)用,把它掛入系統(tǒng)。鉤子的種類很多,每種鉤子可以截獲并處置相鉤子的種類很多,每種鉤子可以截
36、獲并處置相應(yīng)的音訊,每當(dāng)特定的音訊發(fā)出,在到達(dá)目的應(yīng)的音訊,每當(dāng)特定的音訊發(fā)出,在到達(dá)目的窗口之前,鉤子程序先行截獲該音訊、得到對窗口之前,鉤子程序先行截獲該音訊、得到對此音訊的控制權(quán)。此時鉤子函數(shù)可以對截獲的此音訊的控制權(quán)。此時鉤子函數(shù)可以對截獲的音訊進(jìn)展加工處置,甚至可以強迫終了音訊的音訊進(jìn)展加工處置,甚至可以強迫終了音訊的傳送。傳送。這有點類似與這有點類似與MFC中的中的PreTranslateMessage函數(shù),所不同的是該函數(shù)只能用于攔截本進(jìn)程函數(shù),所不同的是該函數(shù)只能用于攔截本進(jìn)程中的音訊,而對系統(tǒng)音訊那么無能為力。中的音訊,而對系統(tǒng)音訊那么無能為力。 Win32系統(tǒng)鉤子的實現(xiàn)系統(tǒng)
37、鉤子的實現(xiàn) 每種類型的鉤子均由系統(tǒng)來維護(hù)一個鉤每種類型的鉤子均由系統(tǒng)來維護(hù)一個鉤子鏈,最近安裝的鉤子位于鏈的開場,子鏈,最近安裝的鉤子位于鏈的開場,擁有最高的優(yōu)先級,而最先安裝的鉤子擁有最高的優(yōu)先級,而最先安裝的鉤子那么處在鏈的末尾。那么處在鏈的末尾。要實現(xiàn)要實現(xiàn)Win32的系統(tǒng)鉤子,首先要調(diào)用的系統(tǒng)鉤子,首先要調(diào)用SDK中的中的API函數(shù)函數(shù)SetWindowsHookEx來來安裝這個鉤子函數(shù),其原型是:安裝這個鉤子函數(shù),其原型是: HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThread
38、Id); 其中:其中: 第一個參數(shù)是鉤子的類型,常用的有第一個參數(shù)是鉤子的類型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等;等; 第二個參數(shù)是鉤子函數(shù)的地址,當(dāng)鉤子鉤到任何音訊后第二個參數(shù)是鉤子函數(shù)的地址,當(dāng)鉤子鉤到任何音訊后便調(diào)用這個函數(shù);便調(diào)用這個函數(shù); 第三個參數(shù)是鉤子函數(shù)所在模塊的句柄;第三個參數(shù)是鉤子函數(shù)所在模塊的句柄; 第四個參數(shù)是鉤子相關(guān)函數(shù)的第四個參數(shù)是鉤子相關(guān)函數(shù)的ID用以指定想讓鉤子去鉤用以指定想讓鉤子去鉤哪個線程,為哪個線程,為0時那么攔截整個系統(tǒng)的音訊此時為全局鉤時那么攔截整個系統(tǒng)的音訊此時為全局鉤子。假設(shè)指定確定的線程,即為線程公用
39、鉤子。子。假設(shè)指定確定的線程,即為線程公用鉤子。 全局鉤子函數(shù)必需包含在全局鉤子函數(shù)必需包含在DLL動態(tài)鏈動態(tài)鏈接庫中,而線程公用鉤子那么可包含接庫中,而線程公用鉤子那么可包含在可執(zhí)行文件中。在可執(zhí)行文件中。得到控制權(quán)的鉤子函數(shù)在處置完音訊后,得到控制權(quán)的鉤子函數(shù)在處置完音訊后,可以調(diào)用另外一個可以調(diào)用另外一個SDK中的中的API函數(shù)函數(shù)CallNextHookEx來繼續(xù)傳送該音訊。也來繼續(xù)傳送該音訊。也可以經(jīng)過直接前往可以經(jīng)過直接前往TRUE來丟棄該音訊,來丟棄該音訊,阻止該音訊的傳送。阻止該音訊的傳送。運用全局鉤子函數(shù)時需求以運用全局鉤子函數(shù)時需求以DLL為載體,為載體,VC6中有三種方式
40、的中有三種方式的MFC DLL可供選擇,即規(guī)范可供選擇,即規(guī)范靜態(tài)鏈接靜態(tài)鏈接MFC DLL、規(guī)范動態(tài)鏈接、規(guī)范動態(tài)鏈接MFC DLL以及擴展以及擴展MFC DLL。第一種第一種DLL在編譯時把運用的在編譯時把運用的MFC代碼鏈接代碼鏈接到到DLL中,執(zhí)行程序時不需求其他中,執(zhí)行程序時不需求其他MFC動態(tài)動態(tài)鏈接類庫的支持,但體積較大;鏈接類庫的支持,但體積較大;第二種第二種DLL在運轉(zhuǎn)時動態(tài)鏈接到在運轉(zhuǎn)時動態(tài)鏈接到MFC類庫,類庫,因此體積較小,但卻依賴于因此體積較小,但卻依賴于MFC動態(tài)鏈接類庫動態(tài)鏈接類庫的支持;這兩種的支持;這兩種DLL均可被均可被MFC程序和程序和Win32程序運用。
41、程序運用。第三種第三種DLL的也是動態(tài)銜接,但做為的也是動態(tài)銜接,但做為MFC類類庫的擴展,只能被庫的擴展,只能被MFC程序運用。程序運用。 Win32 DLL BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved);其中:其中:第一個參數(shù)表示第一個參數(shù)表示DLL的實例句柄;的實例句柄;第三個參數(shù)系統(tǒng)保管;第三個參數(shù)系統(tǒng)保管;第二個參數(shù)指明了當(dāng)前調(diào)用該動態(tài)銜接庫的形狀,第二個參數(shù)指明了當(dāng)前調(diào)用該動態(tài)銜接庫的形狀,它有四個能夠的值:它有四個能夠的值: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)程的空間都是相互獨立環(huán)境下,一切進(jìn)程的空間都是相互獨立的,這減少了運用程序間的相互影響,但大大添加了的,這減少了運用程序間的相互影響,但大大添加了編程的難度。編程的難度。 當(dāng)進(jìn)程在動態(tài)加載當(dāng)進(jìn)程在動態(tài)加載DLL時,系統(tǒng)自動把時,系統(tǒng)自動把DLL地址映射地址映射到該進(jìn)程的私有空間到該進(jìn)程的私有空間; 而且也復(fù)制該而且也復(fù)制該DLL的全局?jǐn)?shù)據(jù)的一份拷貝到該進(jìn)程空的全局?jǐn)?shù)
43、據(jù)的一份拷貝到該進(jìn)程空間,每個進(jìn)程所擁有的一樣的間,每個進(jìn)程所擁有的一樣的DLL的全局?jǐn)?shù)據(jù)其值卻的全局?jǐn)?shù)據(jù)其值卻并不一定是一樣的。并不一定是一樣的。 當(dāng)當(dāng)DLL內(nèi)存被映射到進(jìn)程空間中,每個進(jìn)程都有本人內(nèi)存被映射到進(jìn)程空間中,每個進(jìn)程都有本人的全局內(nèi)存拷貝,加載的全局內(nèi)存拷貝,加載DLL的每一個新的進(jìn)程都重新的每一個新的進(jìn)程都重新初始化這一內(nèi)存區(qū)域,也就是說進(jìn)程不能再共享初始化這一內(nèi)存區(qū)域,也就是說進(jìn)程不能再共享DLL。全局共享數(shù)據(jù)的實現(xiàn)全局共享數(shù)據(jù)的實現(xiàn) 在在Win32環(huán)境下要想在多個進(jìn)程中共享環(huán)境下要想在多個進(jìn)程中共享數(shù)據(jù),就必需進(jìn)展必要的設(shè)置。數(shù)據(jù),就必需進(jìn)展必要的設(shè)置。一種方法便是把這些
44、需求共享的數(shù)據(jù)單一種方法便是把這些需求共享的數(shù)據(jù)單獨分別出來,放置在一個獨立的數(shù)據(jù)段獨分別出來,放置在一個獨立的數(shù)據(jù)段里,并把該段的屬性設(shè)置為共享,建立里,并把該段的屬性設(shè)置為共享,建立一個內(nèi)存共享的一個內(nèi)存共享的DLL。 #pragma data_seg用用#pragma data_seg建立一個新的數(shù)據(jù)段并定義建立一個新的數(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語句之間聲明的變量都語句之間聲明的變量都將在將在shareddata段中。僅定義一個數(shù)據(jù)段還不能段中。僅定義一個數(shù)據(jù)段還不能到達(dá)共享數(shù)據(jù)的目的,還要通知編譯器該段的屬到達(dá)共享數(shù)據(jù)的目的,還要通知編譯器該段的屬性,有兩種方法可
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 脂肪肝試題及答案解析
- 2025年度配電線路安規(guī)考試題庫及答案(共154題)
- 基于2025年的教育園區(qū)建設(shè)社會穩(wěn)定風(fēng)險評估與風(fēng)險評估體系優(yōu)化報告
- 探討家具設(shè)計師職業(yè)素養(yǎng)與專業(yè)技能題試題及答案
- 聚焦2025互聯(lián)網(wǎng)+教育示范項目資金申請可行性分析報告
- 2025南航招聘測試題及答案
- 未來挑戰(zhàn)2025年物理試題及答案
- 聚焦2025:廣播影視行業(yè)媒體融合與內(nèi)容創(chuàng)新趨勢研究報告
- 施工現(xiàn)場作業(yè)安全技能考核試題及答案
- 生態(tài)環(huán)境保護(hù)與土木工程試題及答案
- 2024年甘肅蘭州事業(yè)單位考試真題
- 2025年導(dǎo)游從業(yè)資格通關(guān)秘籍
- 中國法院知識產(chǎn)權(quán)司法保護(hù)狀況2024
- 四川省綿陽市2025屆高三下學(xué)期第三次診斷性測試數(shù)學(xué)試卷(含答案)
- 外賣配送員工作流程總結(jié)
- 新式茶飲產(chǎn)業(yè)的技術(shù)發(fā)展現(xiàn)狀與未來創(chuàng)新趨勢
- 【國浩律師事務(wù)所】2025中國企業(yè)出海戰(zhàn)略與法律支持需求調(diào)研報告
- 2025中國低空經(jīng)濟城市發(fā)展指數(shù)報告
- 當(dāng)代中國外交(外交學(xué)院)知到智慧樹章節(jié)測試課后答案2024年秋外交學(xué)院
- 小學(xué)科學(xué)湘科版六年級下冊全冊同步練習(xí)含答案
- 談院系兩級管理體制下實驗中心與教研室的關(guān)系
評論
0/150
提交評論