




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第九講動態(tài)鏈接庫2/6/2023內(nèi)容安排動態(tài)鏈接庫Win32DLL的創(chuàng)建顯式加載方式加載DLLDllMain函數(shù)動態(tài)鏈接庫概述MFCDLL隱式鏈接方式加載DLL2/6/20232動態(tài)鏈接庫概述動態(tài)鏈接庫不能直接運行,不能接收消息。它們是一些獨立的文件,其中包含能被可執(zhí)行程序或其它DLL調(diào)用來完成某項工作的函數(shù)。只有在其它模塊調(diào)用動態(tài)鏈接庫中的函數(shù)時,它才發(fā)揮作用。微軟任何一個版本的Windows操作系統(tǒng),動態(tài)鏈接庫(DLL)都是其核心和基礎。
WindowsAPI中的所有函數(shù)都包含在DLL中。其中有3個最重要的DLL,Kernel32.dll,它包含用于管理內(nèi)存、進程和線程的各個函數(shù);User32.dll,它包含用于執(zhí)行用戶界面任務(如窗口的創(chuàng)建和消息的傳送)的各個函數(shù);GDI32.dll,它包含用于畫圖和顯示文本的各個函數(shù)。Dll概述2/6/20233動態(tài)鏈接庫概述靜態(tài)庫(LIB)和動態(tài)庫(DLL)
靜態(tài)庫:函數(shù)和數(shù)據(jù)被編譯進一個二進制文件(通常擴展名為.LIB)。在使用靜態(tài)庫的情況下,在編譯鏈接可執(zhí)行文件時,鏈接器從庫中復制這些函數(shù)和數(shù)據(jù),并把它們和應用程序的其它模塊組合起來創(chuàng)建最終的可執(zhí)行文件(.EXE文件)。在使用動態(tài)庫的時候,往往提供兩個文件:一個引入庫和一個DLL。引入庫包含被DLL導出的函數(shù)和變量的符號名,DLL包含實際的函數(shù)和數(shù)據(jù)。在編譯鏈接可執(zhí)行文件時,只需要鏈接引入庫,DLL中的函數(shù)代碼和數(shù)據(jù)并不復制到可執(zhí)行文件中,在運行的時候,再去加載DLL,訪問DLL中導出的函數(shù)。2/6/20234動態(tài)鏈接庫概述使用動態(tài)鏈接庫的好處增強程序的擴展性可以采用多種編程語言來寫提供二次開發(fā)的平臺簡化項目管理節(jié)省磁盤空間和內(nèi)存有助于資源共享2/6/20235內(nèi)容安排Win32DLL的創(chuàng)建顯式加載方式加載DLLDllMain函數(shù)動態(tài)鏈接庫概述MFCDLL隱式鏈接方式加載DLL動態(tài)鏈接庫2/6/20236Win32DLL的創(chuàng)建創(chuàng)建Dll文件新建一個Win32Dynamic-LinkLibrary工程,在AppWizard的第一步選擇“AnemptyDllproject”,創(chuàng)建一個空的動態(tài)鏈接庫工程。添加一個C++源文件:Dll.cpp,在其中寫入如下代碼:intadd(inta,intb){ returna+b;}intsubtract(inta,intb){ returna-b;}Build后,在Debug目錄下會產(chǎn)生一個Dll1.dll文件。2/6/20237Win32DLL的創(chuàng)建導出DLL中的函數(shù)
注意:應用程序如果想要訪問DLL中的函數(shù),那么該函數(shù)必須是已經(jīng)被導出的函數(shù)。為了讓DLL導出函數(shù),需要在每一個將要被導出的函數(shù)前添加標識符:_declspec(dllexport)。_declspec(dllexport)intadd(inta,intb){ returna+b;}_declspec(dllexport)intsubtract(inta,intb){ returna-b;}Build后,在Debug目錄下會產(chǎn)生一個動態(tài)庫Dll1.dll文件和一個引入庫文件Dll1.lib。2/6/20238Win32DLL的創(chuàng)建導出DLL中的類在動態(tài)鏈接庫中,除了函數(shù)能被導出,C++類同樣也能夠被導出。為了讓DLL導出類,在DLL中定義類時,需要在class關鍵字和類名之間加入標識符:_declspec(dllexport)。
注意:在訪問導出類的函數(shù)時,仍受限于函數(shù)自身的訪問權限。也就是說,如果該類的某個函數(shù)訪問權限不是Pubilc,那么外部程序仍無法訪問這個函數(shù)。另外,在實現(xiàn)動態(tài)鏈接庫時,可以不導出整個類,而只導出該類中的某些成員函數(shù)。具體做法是將標識符添加到成員函數(shù)前。2/6/20239內(nèi)容安排Win32Dll
的創(chuàng)建顯式加載方式加載DLLDllMain函數(shù)動態(tài)鏈接庫概述MFCDLL隱式鏈接方式加載DLL動態(tài)鏈接庫2/6/202310隱式鏈接方式加載DLLDLL測試程序新建一個基于對話框的MFC應用程序,在主對話框資源上放置兩個按鈕“Add”和“Subtract”,編寫如下響應函數(shù):voidCDllTestDlg::OnAdd(){ CStringstr; str.Format("7+5=%d",add(7,5)); MessageBox(str);}voidCDllTestDlg::OnSubtract(){ CStringstr; str.Format("7-5=%d",subtract(7,5)); MessageBox(str);}2/6/202311隱式鏈接方式加載DLLexternintadd(inta,intb);externintsubtract(inta,intb);voidCDllTestDlg::OnAdd(){ CStringstr; str.Format("7+5=%d",add(7,5)); MessageBox(str);}voidCDllTestDlg::OnSubtract(){ CStringstr; str.Format("7-5=%d",subtract(7,5)); MessageBox(str);}利用extern聲明外部函數(shù)以上程序編譯提示兩個錯誤:不認識函數(shù)add與subtract。因此,需對這兩個函數(shù)做一個聲明。
extern
關鍵字表明函數(shù)是在外部定義的2/6/202312隱式鏈接方式加載DLL以上程序能夠成功通過編譯,但在程序鏈接時會產(chǎn)生三個錯誤,因為此時鏈接器不知道這兩個函數(shù)是在哪個地方實現(xiàn)的。為了解決這個問題,就需要利用動態(tài)鏈接庫的引入庫文件。引入庫文件并沒有包含實際的代碼,它是用來為鏈接程序提供必要的信息,以便在可執(zhí)行文件中建立動態(tài)鏈接時需要用到的重定位表。使用引入庫文件2/6/202313隱式鏈接方式加載DLL加入引入庫的兩種方法加載之前先把dll1.lib復制到dlltest工程目錄中:方法一:選擇“project\Settings”命令,選擇link選項卡,在“Object/librarymodules”選項編輯框中輸入:dll1.lib方法二:
通過“addfilestoproject…”直接將dll1.lib加入到工程中。2/6/202314隱式鏈接方式加載DLL除了使用extern關鍵字表明函數(shù)是外部定義的之外,還可以使用標識符:_declspec(dllimport)來表明函數(shù)是從動態(tài)鏈接庫中引入的。與使用extern相比,使用_declspec(dllimport)將告訴編譯器該函數(shù)是來源于動態(tài)鏈接庫,從而編譯器可以生成運行效率更高的代碼。利用_declspec(dllimport)聲明外部函數(shù)_declspec(dllimport)intadd(inta,intb);_declspec(dllimport)subtract(inta,intb);2/6/202315隱式鏈接方式加載DLL為查看一個可執(zhí)行模塊依賴的動態(tài)鏈接庫,VisualStudio提供了一個圖形化工具——Depends來實現(xiàn)。位于:“MicrosoftVisualStudio6.0\MicrosoftVisualStudio6.0Tools”菜單中。Depends工具在Depends窗口中,左上方的窗格中顯示了應用程序需要訪問的DLL文件名稱;當選中其中的一個DLL時,右上方的窗格列出了該DLL中被可執(zhí)行程序調(diào)用的函數(shù);右下方的窗格列出了DLL所導出的函數(shù)。2/6/202316內(nèi)容安排Win32DLL的創(chuàng)建顯式加載方式加載DLLDllMain函數(shù)動態(tài)鏈接庫概述MFCDLL隱式鏈接方式加載DLL動態(tài)鏈接庫2/6/202317顯式加載方式加載DLLLoadLibrary函數(shù)HMODULELoadLibrary(LPCTSTRlpFileName);該函數(shù)的作用是將指定的可執(zhí)行模塊映射到調(diào)用進程的地址空間。LoadLibrary不僅能夠加載DLL,還可以加載可執(zhí)行模塊(*.exe),當加載可執(zhí)行模塊時,主要是為了訪問該模塊內(nèi)的資源,例如對話框資源、圖標或位圖資源。當獲取到動態(tài)鏈接庫模塊的句柄后,接下來需要獲取該動態(tài)鏈接庫中導出函數(shù)的地址。2/6/202318顯式加載方式加載DLLGetProcAddress函數(shù)FARPROCGetProcAddress(HMOUDLEhModule,LPCSTRlpProcName);該函數(shù)的作用是用來獲取DLL導出函數(shù)的地址。hModule:指定DLL模塊的句柄,即LoadLibrary函數(shù)的返回值。LpProcName:字符指針,指定DLL導出函數(shù)的名字或函數(shù)的序號。2/6/202319顯式加載方式加載DLL顯示加載DLL實例voidCDllTestDlg::OnAdd(){ HMODULEhModule; hModule=LoadLibrary("Dll1.dll");
typedefint(*FUNC)(inta,intb);//定義函數(shù)指針類型 FUNCadd=(FUNC)GetProcAddress(hModule,"add"); if(!add) { MessageBox("獲取函數(shù)地址失?。?); return; } CStringstr; str.Format("7+5=%d",add(7,5)); MessageBox(str);}2/6/202320顯式加載方式加載DLL名字改編問題上述程序運行會談處消息框“獲取函數(shù)地址失??!”,原因如下:C++編譯器在生成DLL時,會對導出的函數(shù)進行名字改編,并且不同的編譯器使用的改編規(guī)則不一樣,因此改編后的名字不一樣的。因此,GetProcAddress的第二個參數(shù)需要寫改編后的函數(shù)名。(改編后的函數(shù)名字可通過Depends工具查到)FUNCadd=(FUNC)GetProcAddress(hModule,"?add@@YAHHH@Z");2/6/202321顯式加載方式加載DLL名字改編問題(續(xù))如果希望動態(tài)鏈接庫在編譯時,導出函數(shù)的名稱不要發(fā)生改變,在定義導出函數(shù)時,需要加上限定符:extern"C"extern"C"_declspec(dllexport)intadd(inta,intb){ returna+b;}extern"C"_declspec(dllexport)intsubtract(inta,intb){ returna-b;}extern“C”可以解決C++對C語言之間的函數(shù)名改編問題,但這種方法有一個缺陷,就是不能用于導出一個類的成員函數(shù),只能用于導出全局函數(shù)這種情況。2/6/202322內(nèi)容安排Win32Dll
的創(chuàng)建顯式加載方式加載DllDllMain函數(shù)動態(tài)鏈接庫概述MFCDll隱式鏈接方式加載Dll動態(tài)鏈接庫2/6/202323DllMain函數(shù)DllMain函數(shù)介紹一個Win32程序,對可執(zhí)行模塊來說,其入口函數(shù)是WinMain;而對DLL來說,其入口函數(shù)是DllMain,該函數(shù)是可選的。也就是說,在編寫DLL程序時,可以提供也可以不提供DllMain函數(shù)。
注意:如果提供了DllMain函數(shù),那么在此函數(shù)中不要進行太復雜的調(diào)用。因為在加載該動態(tài)鏈接庫時,user32.dll或GDI32.dll等一些Windows核心DLL還沒有
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 度退休人員兼職合同模板
- 2023-2024學年大連理工版小學信息技術五年級下冊奇妙的編碼(教學設計)
- 2023-2024學年滬科版(2019)高中信息技術必修一3.4《分析歷史氣溫數(shù)據(jù)-設計批量數(shù)據(jù)算法》教學設計
- 10青山處處埋忠骨教學設計-2024-2025學年五年級下冊語文統(tǒng)編版
- 餐廳股權合同范本
- 甜品批發(fā)合同范本
- 5 我愛我們班 教學設計-2024-2025學年道德與法治二年級上冊統(tǒng)編版
- 2 百分數(shù)(二)成數(shù) 第二課時(教學設計)-2023-2024學年六年級下冊數(shù)學人教版
- 24“諾曼底號”遇難記 教學設計-2023-2024學年四年級下冊語文統(tǒng)編版
- 店面貸款合同范本
- 腰椎間盤突出癥護理查房課件
- 第15課人機對話的實現(xiàn)(教學設計)六年級上冊信息技術浙教版
- 學校托管工作方案
- 腎性高血壓的護理查房
- 醫(yī)療巡視與巡查制度
- 第11課 社會歷史的主體-【中職專用】2024年中職思想政治《哲學與人生》金牌課件(高教版2023·基礎模塊)
- 六年級成長冊課件
- 大學創(chuàng)意寫作(葛紅兵第二版)課件全套 第1-8章 科學活動與科技結構-廣告文案與軟文
- 2023高考數(shù)學藝考生一輪復習基礎講義(學生版)
- 教師年度考核表
- 中層管理人員競聘試題大全
評論
0/150
提交評論