控制臺(tái)下的DLL動(dòng)態(tài)連接庫的開發(fā)_第1頁
控制臺(tái)下的DLL動(dòng)態(tài)連接庫的開發(fā)_第2頁
控制臺(tái)下的DLL動(dòng)態(tài)連接庫的開發(fā)_第3頁
控制臺(tái)下的DLL動(dòng)態(tài)連接庫的開發(fā)_第4頁
控制臺(tái)下的DLL動(dòng)態(tài)連接庫的開發(fā)_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

控制臺(tái)下的DLL動(dòng)態(tài)連接庫的

開發(fā)摘要:通常在開發(fā)大型的應(yīng)用軟件系統(tǒng)時(shí),為了提高代碼的重用性,降低代碼間的耦合度,一般會(huì)采用模塊化的編程方式,將應(yīng)用程序分成很多模塊,這些模塊分別完成相對(duì)獨(dú)立的功能,它們彼此協(xié)作構(gòu)成整個(gè)軟件系統(tǒng)。在編程過程中可能有一些模塊的功能較為通用,在構(gòu)建其它軟件系統(tǒng)時(shí)仍然可以使用。于是Windows系統(tǒng)平臺(tái)提供了一種有效的編程和運(yùn)行環(huán)境,可以將獨(dú)立的程序模塊創(chuàng)建為較小的動(dòng)態(tài)連接庫-DLL(DynamicLinkLibrary/res)文件,并可對(duì)它們單獨(dú)編譯和測試。本文簡要說明了動(dòng)態(tài)連接庫的結(jié)構(gòu)與開發(fā)過程,給出了應(yīng)用程序調(diào)用DLL庫的幾種方式和相應(yīng)的語言程序,討論了函數(shù)參數(shù)傳遞的兩種形式。關(guān)鍵詞:動(dòng)態(tài)連接庫靜態(tài)連接庫MFC類庫標(biāo)準(zhǔn)接口擴(kuò)展接口第一章動(dòng)態(tài)連接庫的概念與創(chuàng)建動(dòng)態(tài)連接庫的基本概念動(dòng)態(tài)連接庫(DynamicLinkLibrary,DLL)是Windows編程的重要特點(diǎn)之一,它使得Windows應(yīng)用程序可以共享DLL資源和代碼,即在內(nèi)存中只保留一份DLL程序庫,由多個(gè)應(yīng)用程序調(diào)用同一DLL副本,這在Windows這一多任務(wù)操作環(huán)境中可以大大的提高程序的執(zhí)行效率,節(jié)省寶貴的資源,實(shí)際上Windows本身也包括幾個(gè)重要DLL庫,如GDI.EXE,USER.EXE,KERNEL.EXE均為動(dòng)態(tài)連接庫。Windows應(yīng)用程序是一個(gè)可執(zhí)行文件(EXE),它通常創(chuàng)建一個(gè)或幾個(gè)窗口,并使用消息循環(huán)接收用戶輸入。動(dòng)態(tài)連接庫是一種包含函數(shù)和數(shù)據(jù)的模塊,通常并不能直接執(zhí)行,它們是一些獨(dú)立的文件(通常是DLL文件),其中包含能被應(yīng)用程序或其他DLL調(diào)用完成一定功能的函數(shù)。只有在其它模塊調(diào)用DLL中的函數(shù)時(shí)才起作用。在運(yùn)行時(shí),只有當(dāng)EXE程序確實(shí)要調(diào)用這些DLL模塊的情況下,系統(tǒng)才會(huì)將它們裝載到內(nèi)存空間中。這種方式不僅減少了EXE文件的大小和對(duì)內(nèi)存空間的需求,而且使這些DLL模塊可以同時(shí)被多個(gè)應(yīng)用程序使用。在程序開發(fā)中,將各種目標(biāo)模塊(OBJ),運(yùn)行庫(LIB)文件,以及已編譯的資源(RES)文件連接在一起,創(chuàng)建可執(zhí)行文件(EXE),這種連接稱為“靜態(tài)連接”。而“動(dòng)態(tài)連接”發(fā)生在運(yùn)行時(shí)刻,是在運(yùn)行時(shí)將已經(jīng)編譯調(diào)試好的DLL文件裝入,它映射到調(diào)用程序進(jìn)程的虛擬地址空間中。DLL并不是一個(gè)獨(dú)立的可執(zhí)行程序,類似于傳統(tǒng)編程的庫程序,用戶可以將他入或自己編制的DLL連接到應(yīng)用程序中,但傳統(tǒng)編程的庫連接是靜態(tài)連接(StaticLinkLibrary),將庫程序中的代碼和數(shù)據(jù)復(fù)制到自己的程序中,這在DOS環(huán)境下無疑提高了編程效率、但在Windows多任務(wù)環(huán)境下有可能同時(shí)運(yùn)行多個(gè)應(yīng)用程序,如果其中有兩個(gè)以上的應(yīng)用程序使用了同一靜態(tài)庫中的函數(shù),那么內(nèi)存中就會(huì)同時(shí)出現(xiàn)兩份相同的數(shù)據(jù)和代碼,這顯然浪費(fèi)了內(nèi)存資源,降低了效率,開發(fā)DLL程序就是為了避免出現(xiàn)這種情況。相比靜態(tài)連接庫動(dòng)態(tài)連接庫的優(yōu)點(diǎn):當(dāng)多個(gè)應(yīng)用程序同時(shí)調(diào)用同一個(gè)DLL時(shí),所有程序?qū)⒐蚕碓揇LL在物理內(nèi)存的同一份副本,這樣節(jié)省了內(nèi)存空間,減少了數(shù)據(jù)交換的系統(tǒng)開銷;DLL可以獨(dú)立編譯、調(diào)試,當(dāng)對(duì)DLL進(jìn)行更改和升級(jí)時(shí),只要DLL中出口函數(shù)的名稱、參數(shù)、調(diào)用方式和返回值不發(fā)生改變,調(diào)用該DLL的應(yīng)用程序不需要重新編譯和調(diào)試;可以跨平臺(tái)調(diào)用,DLL的編制與具體的編程語言及編譯器無關(guān),只要在開發(fā)DLL時(shí)遵循通用的標(biāo)準(zhǔn),用一種編程語言開發(fā)的應(yīng)用程序可以調(diào)用其它編程語言開發(fā)的DLL,這增加了DLL的通用性。DLL通常采用.DLL為擴(kuò)展名,但也有用°DRV、.FON、.EXE等為擴(kuò)展名的.例如各種驅(qū)動(dòng)文件KEYBOARD.DRV,SOUND.DRV,視頻和打印驅(qū)動(dòng)等都是DLL,各種字體資源文件(.FON)也是DLL,只不過其中存儲(chǔ)的既不是代碼也不是數(shù)據(jù),而是可供其它Windows程序使用的字模,雖然DLL可以有任意擴(kuò)展名,但只有具有標(biāo)準(zhǔn)動(dòng)態(tài)連接庫擴(kuò)展名.DLL的動(dòng)態(tài)連接庫會(huì)被Windows自動(dòng)裝入,其它擴(kuò)展名的DLL必須顯示用LoadLibrary函數(shù)調(diào)入。創(chuàng)建動(dòng)態(tài)連接庫1.2.1動(dòng)態(tài)連接庫的創(chuàng)建方式動(dòng)態(tài)連接庫的創(chuàng)建方式主要可以分為C語言直接創(chuàng)建、MFC類庫創(chuàng)建兩大類。直接用C語言寫的DLL,其輸出的函數(shù)一般用的是標(biāo)準(zhǔn)C接口來實(shí)現(xiàn)的,并且能夠被非MFC和MFC編寫的應(yīng)用程序所調(diào)用,其通用性比較強(qiáng),方便調(diào)用和整合。使用MFC類庫編寫的DLL主要可以分為兩種:規(guī)則的動(dòng)態(tài)連接庫和擴(kuò)展動(dòng)態(tài)連接庫。規(guī)則動(dòng)態(tài)鏈接庫(RegularDLL)明顯的特點(diǎn)是在源文件里有一個(gè)繼承CWinApp的類,DllMain函數(shù)被MFC所提供,不需顯式的寫出來。其又可細(xì)分成靜態(tài)連接到MFC和動(dòng)態(tài)連接到MFC兩種。規(guī)則動(dòng)態(tài)鏈接庫(RegularDLL)能夠被所有支持DLL技術(shù)的語言所編寫的應(yīng)用程序調(diào)用?!癕GS圖形軟件開發(fā)包”提供的動(dòng)態(tài)鏈接庫mgsdll.dll、mgsSmap.dll和MgsEtSymdu就是規(guī)則動(dòng)態(tài)鏈接庫(RegularDLL)。擴(kuò)展動(dòng)態(tài)鏈接庫(ExtensionDLL)用來實(shí)現(xiàn)從MFC所繼承下來的類的重新利用,也就是說,用這種類型的動(dòng)態(tài)連接庫,可以用來輸出一個(gè)從MFC所繼承下來的類。它輸出的函數(shù)僅可以被使用MFC且動(dòng)態(tài)鏈接到MFC的應(yīng)用程序使用??梢詮腗FC繼承你所想要的、更適于你自己用的類,并把它提供給應(yīng)用程序。也可隨意的給應(yīng)用程序提供MFC或MFC繼承類的對(duì)象指針。擴(kuò)展動(dòng)態(tài)鏈接庫(ExtensionDLL)使用MFC的動(dòng)態(tài)連接版本創(chuàng)建,它只能被用MFC類庫所編寫的應(yīng)用程序所調(diào)用。擴(kuò)展動(dòng)態(tài)鏈接庫(ExtensionDLL)和規(guī)則動(dòng)態(tài)鏈接庫(RegularDLL)不一樣,它沒有一個(gè)從CWinApp繼承而來的類的對(duì)象,所以,你必須為自己的DllMain函數(shù)添加初始化代碼和結(jié)束代碼。DLL的建立同標(biāo)準(zhǔn)的Windows程序相類似每個(gè)DLL都有一個(gè)入口函數(shù)(LibMain),程序體函數(shù)(MainRoutine)和出口函數(shù)(WEP),其中只有入口函數(shù)是必需的.DLL可以具有自己的實(shí)例句柄,資源,數(shù)據(jù)段和局部堆,但是沒有自己的堆棧只能使用調(diào)用者的堆棧.在中小模式下程序數(shù)據(jù)段與堆棧段通常指向同一段地址,因此DLL在此情況下有可能發(fā)生DS=SS的錯(cuò)誤,必須在編譯時(shí)設(shè)置相應(yīng)的選項(xiàng)來檢查這些錯(cuò)誤。1.2.2動(dòng)態(tài)連接庫的創(chuàng)建規(guī)則DLL函數(shù)不能使用Windows的消息循環(huán),它的模塊定義文件也必須符合以下一些限制:NAME段聲明為LIBRARY,其聲明的名稱為生成的DLL庫名;DATA段聲明中的MULTIPLE項(xiàng)改為SINGLE,因?yàn)镈LL只允許單個(gè)副本;?沒有STACKSIZE聲明,因?yàn)镈LL沒有堆棧??陕暶鱄EAPSIZE段;如果DLL建立出口函數(shù)WEP,則WEP必須包含在EXPORTS聲明中;DLL可以有自己的內(nèi)部函數(shù),但可供其它程序調(diào)用的輸出函數(shù)必須包含在EXPORTS聲明中。一個(gè)DLL中可以有多個(gè)輸出函數(shù),輸出函數(shù)必須用FARPASCAL顯式聲明其函數(shù)原型。DLL的C語言源文件必須包含入口函數(shù)LibMain(),它有4個(gè)入口參數(shù),LibMain()是對(duì)DLL進(jìn)行初始化工作;出口函數(shù)WEP()在DLL被卸載時(shí)作一些必要的清理工作。因此建立一個(gè)動(dòng)態(tài)連接庫至少包含源文件和模塊定義文件兩個(gè)源文件,還可以包括.H頭文件,.RC資源文件等.下面是用BorlandC++IDE建立DLL的幾個(gè)標(biāo)準(zhǔn)框架文件:工程文件名:dlldemo.Prj;工程文件項(xiàng):dlldemo.def,dlldemo.CC語言源文件DLLDEMO.C#include<windows.h>inkFARPASCALexportdemofl(intfarpath,intfar*databuf);intFARPASCALdemof2(intfarpath。intfardata[I28]);intPASCALFARLibMain(HANDLEhlnstance,WORDwDtaseg,WORDwHeapSize.LPSTRIpszCmdline)if(wHeapSize!=0)Unl13ckData(0);return1;intFARPASCALexportdemofl(intfarpath,intfar*databuf);//函數(shù)體for(inti=0;i<l28;i++)*(data+i)=0;return0;intFARPASCALdemof2(intfarpath,intfardata[128])//函數(shù)體for(inti=0;i<128;i++)data[i]=0;return0;函數(shù)demofl()前面的_export限定符直接聲明其為輸出函數(shù),加此限定符后可不用直接在。DEF文件EXPORTS段中聲明其為輸出函數(shù),但此時(shí)應(yīng)用程序只能用輸出函數(shù)原名調(diào)用,而不能使用輸出函數(shù)的別名或序數(shù)名調(diào)用。3)模塊定義文件DLLDEMO.DEFLIBRARYDLLDEMODESCRIPTION'DemoDLLProgram'EXETYPEWINDOWSCODEPRELOADMOVEABLEDATAPRELOADMOVEABLESINGLEHEAPSIZE1024EXPORTSdemofldemof2注意模塊定義在文件中的LIBRARY段和DATA段.在BodandC++IDE(集成調(diào)試環(huán)境)中編輯好以上程序文件后,須先設(shè)置OptionsfApplication選項(xiàng)中的LinkerOutput為WindowsDLL,表明生成DLL庫程序;CompilerJCodeGenerationOptions選項(xiàng)中AssumeSSEqualsDS為Never.然后可以按鍵用Make功能生成DLL庫。第二章調(diào)用動(dòng)態(tài)連接庫DLL編寫調(diào)試好后就可由其它應(yīng)用程序調(diào)用,通常有顯式和隱式兩種調(diào)用方式。2.1顯式調(diào)用方式是由編程者用API函數(shù)加載和卸載DLL來達(dá)到調(diào)用DLL的目的,使用上較復(fù)雜,但能更加有效地使用內(nèi)存,是編制大型應(yīng)用程序時(shí)的重要方式。程序員可以決定DLL文件何時(shí)加載或不加載,顯式鏈接在運(yùn)行時(shí)決定加載哪個(gè)DLL文件。使用DLL的程序在使用之前必須調(diào)用LoadLibrary函數(shù)或MFC提供的AfxLoadLibrary函數(shù)顯式地將動(dòng)態(tài)連接庫調(diào)進(jìn)來,動(dòng)態(tài)連接庫的文件名即是上面兩個(gè)函數(shù)的參數(shù),從而得到一個(gè)DLL模塊的句柄,然后調(diào)用GetProcAddress函數(shù)得到輸出函數(shù)的指針,自此,你就可以象使用本應(yīng)用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在退出之前必須調(diào)用FreeLibrary函數(shù)卸載DLL。調(diào)用過程如下:1)調(diào)用Win32的LoadLibrary函數(shù),并指定DLL的路徑名稱作為參數(shù),返回HINSTANCE(句柄)參數(shù);2)調(diào)用GetProcAddress函數(shù)(使用HINSTANCE和需調(diào)用的函數(shù)符號(hào)名或標(biāo)識(shí)號(hào)作為參數(shù)),GetProcAddress函數(shù)將符號(hào)名或標(biāo)識(shí)號(hào)轉(zhuǎn)換為DLL內(nèi)部的地址,返回函數(shù)指針;3)以返回的函數(shù)指針調(diào)用該函數(shù)。2.2隱式調(diào)用方式由編譯系統(tǒng)完成對(duì)DLL的加載和應(yīng)用程序結(jié)束后對(duì)DLL卸載。程序員在建立一個(gè)DLL文件時(shí),鏈接程序會(huì)自動(dòng)生成個(gè)與之對(duì)應(yīng)的LIB導(dǎo)入文件。該文件包含了每一個(gè)DLL導(dǎo)出數(shù)的符號(hào)名和可選的標(biāo)識(shí)號(hào),但是并不含有實(shí)際的代碼。隱調(diào)用需要把產(chǎn)生動(dòng)態(tài)連接庫時(shí)產(chǎn)生的LIB文件加入到應(yīng)用程的工程中,想使用DLL中的函數(shù)時(shí),只須在頭文件中加以說明LIB文件作為DLL的替代文件被編譯到應(yīng)用程序項(xiàng)目中。當(dāng)序員通過靜態(tài)鏈接方式編譯生成應(yīng)用程序時(shí),應(yīng)用程序中的用函數(shù)與LIB文件中導(dǎo)出符號(hào)相匹配,這些符號(hào)或標(biāo)識(shí)號(hào)進(jìn)到生成的EXE文件中。LIB文件中也包含了對(duì)應(yīng)的DLL文件(但不是完全的路徑名),鏈接程序?qū)⑵浯鎯?chǔ)在EXE文件內(nèi)部當(dāng)應(yīng)用程序運(yùn)行過程中需要加載DLL文件時(shí),Windows根據(jù)這些信息發(fā)現(xiàn)并加載DLL,然后通過符號(hào)名或標(biāo)識(shí)號(hào)實(shí)現(xiàn)對(duì)DLL函數(shù)的動(dòng)態(tài)鏈接。所有被應(yīng)用程序調(diào)用的DLL文件都會(huì)在應(yīng)用程序EXE文件加載時(shí)被加載在到內(nèi)存中??蓤?zhí)行程序鏈接到一個(gè)包含DLL輸出函數(shù)信息的輸入庫文件(LIB文件)。操作系統(tǒng)在加載使用可執(zhí)行程序時(shí)加載DLL??蓤?zhí)行程序直接通過函數(shù)名調(diào)用DLL的輸出函數(shù),調(diào)用方法和程序內(nèi)部其他的函數(shù)是一樣的。當(dāng)DLL使用_declspec(dllexport)關(guān)鍵字的方式導(dǎo)出函數(shù)時(shí)用戶程序在調(diào)用DLL函數(shù)時(shí)必須使用_declspec(dllimport)關(guān)鍵字聲明導(dǎo)入函數(shù).如_declspec(dllimport)voidfunction(void)當(dāng)DLL使用DEF文件方式導(dǎo)出函數(shù)時(shí),只需在頭文件中聲明導(dǎo)入函數(shù),不必在函數(shù)聲明前加上_declspec(dllimport)關(guān)鍵字。采用顯式調(diào)用方式用LoadLibrary函數(shù)調(diào)用DLL,可以指定DLL的路徑。如果沒有指定DLL的路徑或采用隱式調(diào)用方式Windows將遵循下面的搜索順序來定位DLL:包含EXE文件的目錄。進(jìn)程的當(dāng)前工作目錄。Windows系統(tǒng)目錄。Windows目錄。列在Path環(huán)境變量中的一系列目錄。因此,當(dāng)調(diào)用DLL時(shí),需將DLL文

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論