資源描述:
《Windows程序設(shè)計(jì)教程 第2版 教學(xué)課件 作者 王秀梅 第12章-MFC動態(tài)鏈接庫.ppt》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、動態(tài)鏈接庫在Windows中非常重要,幾乎所有的WindowsAPI函數(shù)都包含在動態(tài)鏈接庫中。動態(tài)鏈接庫有很多優(yōu)點(diǎn),如節(jié)省內(nèi)存、支持多語種等,特別是當(dāng)動態(tài)鏈接庫(DLL)中的函數(shù)改變后,只要不是參數(shù)改變,調(diào)用這個(gè)函數(shù)的應(yīng)用程序就不需要重新編譯,這在編程時(shí)是十分有用的。DLL基本理論12.1簡單DLL示例12.2訪問動態(tài)鏈接庫12.3常規(guī)DLL12.4擴(kuò)展DLL12.512.1DLL基本理論在Windows操作系統(tǒng)中,幾乎所有的內(nèi)容都是以DLL的形式存在的。例如顯示的字體和圖標(biāo)存儲在GDI.DLL
2、中;顯示W(wǎng)indows桌面、處理用戶輸入所需要的代碼被存儲在User.DLL中;Windows編程所需要的大量API函數(shù)存儲在Kernel.DLL中。12.1.1DLL基本概念應(yīng)用程序要從目標(biāo)代碼(.obj)外部引用函數(shù),可以通過兩種途徑實(shí)現(xiàn)——靜態(tài)鏈接和動態(tài)鏈接。1.靜態(tài)鏈接該種方式下,鏈接程序首先對庫文件(.lib)進(jìn)行搜索,直到在某個(gè)庫中,找到包含函數(shù)的對象模塊為止。然后,鏈接程序把這個(gè)對象模塊復(fù)制到可執(zhí)行文件(.exe)中。鏈接程序負(fù)責(zé)維護(hù)對該函數(shù)的所有引用。2.動態(tài)鏈接該種方式下,鏈接
3、程序同樣先對庫文件(.lib)進(jìn)行搜索,直到在某個(gè)庫中,找到所引用函數(shù)的輸入記錄為止。動態(tài)鏈接庫主要有如下優(yōu)點(diǎn):(1)系統(tǒng)中,同時(shí)運(yùn)行的多個(gè)應(yīng)用程序可以同時(shí)使用同一個(gè)動態(tài)鏈接庫,它們在內(nèi)存中共享DLL文件的一個(gè)拷貝。這樣做不僅節(jié)省了內(nèi)存,而且減少了文件的動態(tài)交換。(2)只要編寫的應(yīng)用程序的函數(shù)變量、返回值的類型、數(shù)量不發(fā)生變化,動態(tài)鏈接庫的函數(shù)可以不用重新編譯鏈接,直接使用。(3)只要遵循一定的規(guī)則,不同語言編寫的應(yīng)用程序可以調(diào)用同一個(gè)動態(tài)鏈接庫。12.1.2DLL的分類微軟的VisualC++
4、支持3種DLL,它們分別是Non-MFCDLL(非MFCDLL)、RegularDLL(常規(guī)DLL)和ExtensionDLL(擴(kuò)展DLL)。1.Non-MFCDLL(非MFCDLL)2.RegularDLL(常規(guī)DLL)3.ExtensionDLL(擴(kuò)展DLL)12.1.3DLL的工作原理應(yīng)用程序打開動態(tài)鏈接庫時(shí),把動態(tài)鏈接庫的執(zhí)行代碼映射到進(jìn)程的地址空間中,這里的進(jìn)程包括了使用動態(tài)鏈接庫的每一個(gè)進(jìn)程。而動態(tài)鏈接庫中的數(shù)據(jù),應(yīng)用程序則不是通過映射方式獲取,而是做了一個(gè)備份。也就是說動態(tài)鏈接庫所
5、有的執(zhí)行代碼是共享的,但其中的變量,每個(gè)應(yīng)用程序均備份了一份。1.文件映射2.引用表3.內(nèi)存分配12.2簡單DLL示例DLL現(xiàn)在越來越容易編寫,Win32已經(jīng)大大簡化了其編程模式,并有許多來自AppWizard和MFC類庫的支持。本節(jié)將從一個(gè)簡單的非MFCDLL實(shí)例入手,討論DLL的一些主要編程思想。12.2.1一個(gè)簡單的DLL1.DLL的編程實(shí)現(xiàn)圖12.1工程向?qū)?.DLL調(diào)用的編程實(shí)現(xiàn)3.例程分析圖12.2對話框窗口設(shè)計(jì)圖12.3程序運(yùn)行結(jié)果12.2.2導(dǎo)出函數(shù)DLL文件中包含一個(gè)導(dǎo)出函數(shù)表
6、,給出了DLL中每個(gè)導(dǎo)出函數(shù)的名字和標(biāo)識號。另外,函數(shù)表中還包含了DLL中函數(shù)的地址。動態(tài)鏈接過程將在加載DLL模塊時(shí),動態(tài)建立一個(gè)函數(shù)調(diào)用與函數(shù)地址的對應(yīng)表。因此,如果沒有改變導(dǎo)出函數(shù)的名字和參數(shù)序列,則重新編譯或重建DLL文件時(shí)并不需要修改應(yīng)用程序。從DLL導(dǎo)出函數(shù)主要有兩種方式:(1)創(chuàng)建模塊定義文件(.def),并把導(dǎo)出函數(shù)名加入模塊定義文件中;(2)在定義函數(shù)時(shí)使用_declspec(dllexport)關(guān)鍵字。1.使用模塊定義文件導(dǎo)出函數(shù)模塊定義文件是一個(gè)由多個(gè)語句組成的文本文件,根
7、據(jù)不同的DLL,其模塊定義語句可以不同,但一般來說必須包含以下語句:(1)LIBRARY語句。(2)DESCRIPTION語句。(3)EXPORTS語句。2.使用_declspec(dllexport)關(guān)鍵字輸出DLL用戶可以使用_declspec(dllexport)關(guān)鍵字輸出DLL里的數(shù)據(jù)、函數(shù)、類等,這樣就不再需要DEF文件了。12.2.3導(dǎo)入函數(shù)DLL中實(shí)現(xiàn)了導(dǎo)出函數(shù),而在應(yīng)用程序中,必須聲明相應(yīng)的導(dǎo)入函數(shù)。不論DLL中采用的是DEF文件輸出方式,還是_declspec(dllexpor
8、t)輸出方式,在應(yīng)用程序中都可以用_declspec(dllimport)關(guān)鍵字來導(dǎo)入函數(shù)。采用_declspec(dllimport)關(guān)鍵字導(dǎo)入函數(shù)MyFunction(),實(shí)現(xiàn)如下:void_declspec(dllimport)MyFunction();12.3訪問動態(tài)鏈接庫在應(yīng)用程序中訪問DLL,實(shí)際上就是將應(yīng)用程序中的導(dǎo)入函數(shù)與DLL文件中的導(dǎo)出函數(shù)進(jìn)行鏈接。有兩種鏈接方式:隱式鏈接和顯式鏈接。隱式鏈接是指通過編譯器,給應(yīng)用程序提供DLL的名稱和DLL函數(shù)的鏈接地址;顯式鏈接則由應(yīng)用程