Visual C++程序設計教程(第二版)課件:動態(tài)鏈接庫_第1頁
Visual C++程序設計教程(第二版)課件:動態(tài)鏈接庫_第2頁
Visual C++程序設計教程(第二版)課件:動態(tài)鏈接庫_第3頁
Visual C++程序設計教程(第二版)課件:動態(tài)鏈接庫_第4頁
Visual C++程序設計教程(第二版)課件:動態(tài)鏈接庫_第5頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

動態(tài)鏈接庫

13.1DLL基礎知識本節(jié)講述DLL的基礎知識。13.1.1DLL概述 Windows系統(tǒng)平臺上提供了一種完全不同的有效的編程和運行環(huán)境,可以將獨立的程序模塊創(chuàng)建為較小的DLL(DynamicLinkableLibrary)文件,并可對它們單獨編譯和測試。在運行時,只有當EXE程序確實要調用這些DLL模塊的情況下,系統(tǒng)才會將它們裝載到內存空間中。這種方式不僅減少了EXE文件的大小和對內存空間的需求,而且使這些DLL模塊可以同時被多個應用程序使用。Windows自己就將一些主要的系統(tǒng)功能以DLL模塊的形式實現。13.1.2認清DLL與LIB DLL與LIB的相似之處是它們都是將一部分可執(zhí)行代碼以及數據放在庫中供用戶程序使用,而且在使用時,這些代碼就象是用戶程序本身的一部分。LIB文件是靜態(tài)鏈接庫文件,在其中放置了許多的函數和變量。其中一部分函數和變量是供內部使用的,在接口中不可見,即沒有輸出;另一部分是供接口使用的(當然內部函數也可以使用),外部可見,從而應用程序可以調用這些輸出的函數和變量。在DLL中同樣包括許多變量和函數,也分為內部變量、函數和外部接口函數、變量。對于內部的函數和變量,供DLL自己調用,因此并不包含名稱,只使用地址;對于供外部調用的函數和變量,在內部的時候也使用地址,只是在頭文件中包含了輸出變量和函數的名稱,而且包含了這些名稱所對應的地址,即將名稱和地址對應起來。通過這些名稱就可以查找對應變量和函數的地址(函數的地址是指函數入口點的地址)。13.1.3認清DLL與EXEDLL和EXE都是Windows下的可執(zhí)行模塊,在對應的文件結構上,它們也類似的:具有文件頭,重定位信息表,導入動態(tài)庫表等,另外,DLL作為供程序調用的服務者,文件中還包含導出的函數表和變量表。DLL是服務的提供者,主要用來提供輸出變量和函數供別的程序調用,在DLL被裝入的時候,以及進程中創(chuàng)建線程的時候,Windows都會以不同的參數調用入口點函數,然后該函數進行某些初始化工作后返回,DLL的執(zhí)行就停止了。Windows并不為DLL創(chuàng)建單獨的進程空間,而是將其裝入共享地址,然后將其映射到不同的進程供進程調用,從而達到代碼共享的目的。EXE是DLL所提供服務的使用者,調用DLL中的輸出的函數和變量,每一個EXE在運行的時候,Windows均為它創(chuàng)建單獨的進程環(huán)境,包括進程地址空間,EXE就在它的地址空間中運行,對別的進程是不透明的,因此也就無法為別的進程調用,因此在許多情況下只能使用DLL來實現某些功能。13.1.4DLL的兩種動態(tài)鏈接方法加載時動態(tài)鏈接 由編譯系統(tǒng)完成對DLL的加載和應用程序結束時DLL卸載的編碼(如還有其它程序使用該DLL,則Windows對DLL的應用記錄減1,直到所有相關程序都結束對該DLL的使用時才釋放它),簡單實用,但不夠靈活,只能滿足一般要求。運行時動態(tài)鏈接 是由編程者用API函數加載和卸載DLL來達到調用DLL的目的,使用上較復雜,但能更加有效地使用內存,是編制大型應用程序時的重要方式。13.2DLL入/出口函數 Win32DLL與Win16DLL有很大的區(qū)別,這主要是由操作系統(tǒng)的設計思想決定的。一方面,在Win16DLL中程序入口點函數和出口點函數(LibMain和WEP)是分別實現的;而在Win32DLL中卻由同一函數DLLMain來實現。無論何時,當一個進程或線程載入和卸載DLL時,都要調用該函數。13.2.1DllMain函數

每一個DLL必須有一個入口點,DLLMain是一個缺省的入口函數。DLLMain負責初始化(Initialization)和結束(Termination)工作,每當一個新的進程或者該進程的新的線程訪問DLL時,或者訪問DLL的每一個進程或者線程不再使用DLL或者結束時,都會調用DLLMain。但是,使用TerminateProcess或TerminateThread結束進程或者線程,不會調用DLLMain。13.2.2MFCAppWizard生成的RegularDLL入/出口 MFCAppWizard生成的RegularDLL在后面的章節(jié)會有介紹,這里只討論它的入/出口點問題。 每個RegularDLL都有MFCAppWizard自動生成的CWinApp派生類的對象,與其它MFC應用程序一樣,它是在CWinApp派生類的成員函數InitInstance和ExitInstance完成初始化和終止的工作。 實際上,MFC提供了一個基本的DllMain函數,在這種DLL中不必自己編寫DllMain函數,由MFC提供的這個函數在裝載DLL的時候調用InitInstance函數,而在DLL退出的時候調用ExitInstance函數。所需要完成的初始化和終止的工作需要在這兩個函數中完成。13.3從DLL中導出函數

關于DLL的函數動態(tài)鏈接庫中定義有兩種函數:導出函數(exportfunction)和內部函數(internalfunction)。導出函數可以被其它模塊調用,內部函數在定義它們的DLL程序內部使用。13.3.1使用DEF文件導出函數

模塊定義文件(.DEF)是一個或多個用于描述DLL屬性的模塊語句組成的文本文件,每個DEF文件至少必須包含以下模塊定義語句:第一個語句必須是LIBRARY語句,指出DLL的名字;

EXPORTS語句列出被導出函數的名字;將要輸出的函數修飾名羅列在EXPORTS之下,這個名字必須與定義函數的名字完全一致,如此就得到一個沒有任何修飾的函數名了??梢允褂肈ESCRIPTION語句描述DLL的用途(此句可選);“;”對一行進行注釋(可選)。13.3.2使用關鍵字_declspec(dllexport)

使用MFC提供的修飾符號_declspec(DLLexport)在要輸出的函數、類、數據的聲明前加上_declspec(DLLexport)的修飾符,表示輸出。__declspec(DLLexport)在C調用約定、C編譯情況下可以去掉輸出函數名的下劃線前綴。extern"C"使得在C++中使用C編譯方式成為可能。在C++下定義C函數,需要加extern"C"關鍵詞。用extern"C"來指明該函數使用C編譯方式。輸出的C函數可以從C代碼里調用。13.3.3使用AFX_EXT_CLASS導出 MFC擴展DLL使用AFX_EXT_CLASS來導出類,鏈接這種DLL的應用程序或其他DLL使用這個宏來導入類。 如果用于DLL應用程序的實現中,則表示輸出;如果用于使用DLL的應用程序中,則表示輸入。要輸出整個的類,對類使用_declspec(_DLLexpot);要輸出類的成員函數,則對該函數使用_declspec(_DLLexport)。13.4DLL中的數據和內存13.4.1DLL多進程間的數據共享 DLL被多個進程調用,它的代碼從而被映射到不同的進程內存空間之中,DLL共享數據也盡量只在系統(tǒng)中有一個拷貝,這是通過COPY-ON-WRITE技術實現的。 使用共享數據段,首先需要把欲放入數據段的數據定義在特定的數據段中,然后在說明這個數據段是共享數據段就可以了。13.4.2DLL進程中多線程間的數據隔離 WindowsAPI提供了進程中多線程數據分離的一系列TLS(ThreadLocalStorage)函數,這是進程內線程隔離的解決方法,TLS函數集共有四個函數:DWORDTlsAlloc(VOID);BOOLTlsFree(DWORDdwTlsIndex);LPVOIDTlsGetValue(DWORDdwTlsIndex);BOOLTlsSetValue(DWORDdwTlsIndex,LPVOIDlpTlsValue);

函數TlsAlloc用來分配線程局部變量索引,它的返回值是后面三個函數的參數dwTlsIndex。而函數TlsFree負責釋放線程變量索引。所以這兩個函數應該在副線程創(chuàng)建之前的主線程中調用。在DLL模塊中,就是在入口點函數被參數調用時候使用。 線程運行過程中,可以使用函數TlsGetValue和TlsSetValue根據線程變量的索引號存取各自的數據指針,并存取到各自的數據。13.5幾種常用的DLL MFC中的DLLa、Non-MFCDLL:指的是不用MFC的類庫結構,直接用C語言寫的DLL,其輸出的函數一般用的是標準C接口,并能被非MFC的應用程序所調用。13.5.1Win32DLL VC6支持自動生成的Win32DLL和MFCAppWizardDLL,其中自動生成的Win32DLL共包括三種DLL工程。從FILE|NEW菜單項,選擇對話框中的Projects選項卡,圖13.1

選中Win32Dynamic-LinkLiabrary,輸入工程名,點擊OK按鈕后,彈出如下對話框圖13.2所示:選擇所要生成的Win32DLL類型了。13.5.2RegularstaticallylinkedtoMFCDLL

在VC6中有三種形式的MFCDLL(在該DLL中可以使用和繼承已有的MFC類)可供選擇,即RegularstaticallylinkedtoMFCDLL(標準靜態(tài)鏈接MFCDLL)和RegularusingthesharedMFCDLL(標準動態(tài)鏈接MFCDLL)以及ExtensionMFCDLL(擴展MFCDLL)。 第一種DLL的特點是,在編譯時把使用的MFC代碼加入到DLL中,因此,在使用該程序時不需要其他MFC動態(tài)鏈接類庫的存在,但占用磁盤空間比較大;13.5.3RegularusingthesharedMFCDLL

第二種DLL的特點是:在運行時,動態(tài)鏈接到MFC類庫,因此減少了空間的占用,但是在運行時卻依賴于MFC動態(tài)鏈接類庫。動態(tài)鏈接到MFC的規(guī)則DLL應用程序里頭的輸出函數可以被任意Win32程序使用,包括使用MFC的應用程序。但是,所有從DLL輸出的函數應該以如下語句開始:AFX_MANAGE_STATE(AfxGetStaticModuleState())此語句用來正確地切換MFC模塊狀態(tài)。13.5.4MFCExtensionDLL

第三種DLL的特點類似于第二種,作為MFC類庫的擴展,只能被MFC程序使用。

ExtensionDLL用來實現從MFC所繼承下來的類的重新利用,就是說,用這種類型的動態(tài)連接庫,可以用來輸出一個從MFC所繼承下來的類。它輸出的函數僅可以被使用MFC且動態(tài)鏈接到MFC的應用程序使用??梢詮腗FC繼承所想要的,更適于用戶自己用的類,并把它提供給應用程序。也可隨意的給應用程序提供MFC或MFC繼承類的對象指針。ExtensionDLL使用MFC的動態(tài)連接版本所創(chuàng)建的,并且它只被用MFC類庫所編寫的應用程序所調用。13.6DLL的調用和調試13.6.1VC對DLL的調用

系統(tǒng)運行一個調用DLL的程序時,將在以下位置查找該DLL:1.包含EXE文件的目錄2.進程的當前工作目錄3.Windows系統(tǒng)目錄4.Windows目錄5.列在Path環(huán)境變量中的一系列目錄 若找不到該文件,系統(tǒng)將顯示對話框提示并終止程序的執(zhí)行,13.6.2VB對DLL的調用

在VB中調用WindowsDLL之前,必須在Standard(代碼)模塊的Declarations段中加一個特殊的聲明。對于一個DLL或API函數,Declare語句是Windows所必需的,這一點很重要。并且在32位版的VB中動態(tài)鏈接庫中的函數對條件是很敏感的。13.6.3DLL的調試 DLL的調試有很多中方法,但都需要把DLL工程生成的后綴名為.dll的文件放在執(zhí)行它的應用程序可以找到的目錄中。這可以有很多中方法,手工也行的。 應用VC可以很容易地調試DLL,只要從DLL工程中運行調試程序即可。當第一次調試DLL的時候,調試程序會跳出如下對話框圖13.5。13.7DLL例程13.7.1使用已有的DLL

本例程將通過調用DLL來實現程序的隱藏,即不顯示程序窗口,程序不顯示在任務欄上,在按下Ctrl+Alt+Del鍵后出現的任務列表中也不顯示。 首先創(chuàng)建工程:1.在VC++集成開發(fā)環(huán)境中,通過菜單File|New,彈出New對話框;2.在Projects選項卡中選擇MFCAppWizard(exe),在Projectname中輸入“Eg13_1”Location讀者可以自己選擇;3.按下OK按鈕,在彈出的MFCAppWizardStep-1對話框中選擇程序框架為單文檔框架,即選中SingleDocument;4.按下OK按鈕,在彈出的NewProjectInformation對話框中按下OK按鈕后等待創(chuàng)建完相應的工程。參考課本260頁13.7.2資源DLL本例程將建立兩個DLL文件以實現自己的雙語菜單。首先創(chuàng)建工程Eg13_2:1.在VC++集成開發(fā)環(huán)境中,通過菜單File|New,彈出New對話框;2.在Projects選項卡中選擇MFCAppWizard(exe),在Projectname中輸入“Eg13_2”Location讀者可以自己選擇;3.按下OK按鈕,在彈出的MFCAppWizardStep-1對話框中選擇程序框架為單文檔框架,即選中SingleDocument;4.按下Finish按鈕,在彈出的NewProjectInformation對話框中按

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論