欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Visual C++中動(dòng)態(tài)鏈接庫技術(shù)淺談

Visual C++中動(dòng)態(tài)鏈接庫技術(shù)淺談

 引言

    較大的應用程序都由很多模塊組成,這些模塊分別完成相對獨立的功能,它們彼此協(xié)作來(lái)完成整個(gè)軟件系統的工作。在構造軟件系統時(shí),如果將所有模塊的源代碼都靜態(tài)編譯到整個(gè)應用程序的EXE文件中,會(huì )產(chǎn)生一些問(wèn)題:一個(gè)缺點(diǎn)是增加了應用程序的大小,它會(huì )占用更多的磁盤(pán)空間,程序運行時(shí)也會(huì )消耗較大的內存空間,造成系統資源的浪費;另一個(gè)缺點(diǎn)是,在編寫(xiě)大的EXE程序時(shí),在每次修改重建時(shí)都必須調整編譯所有源代碼,增加了編譯過(guò)程的復雜性,也不利于階段性的單元測試;而且,一些模塊的功能可能較為通用,在構造其它軟件系統時(shí)仍會(huì )被使用。

    Windows系統平臺上提供了一種完全不同的較有效的編程和運行環(huán)境,你可以將獨立的程序模塊創(chuàng )建為較小的動(dòng)態(tài)鏈接庫(Dynamic Linkable Library,DLL)文件,并可對它們單獨編譯和測試。在運行時(shí),只有當EXE程序確實(shí)要調用這些DLL模塊的情況下,系統才會(huì )將它們裝載到內存空間中。這種方式不僅減少了EXE文件的大小和對內存空間的需求,而且使這些DLL模塊可以同時(shí)被多個(gè)應用程序使用。

    動(dòng)態(tài)鏈接庫概述

    動(dòng)態(tài)鏈接庫技術(shù)是Windows最重要的實(shí)現技術(shù)之一,Windows的許多新功能、新特性都是通過(guò)DLL來(lái)實(shí)現的。其實(shí),Windows本身就是由許多DLL組成的,它最基本的三大組成模塊Kernel、GDI和User都是DLL.

    一般來(lái)說(shuō),DLL是一種磁盤(pán)文件,以。dll、。DRV、。FON、。SYS和許多以。EXE為擴展名的系統文件都可以是DLL.它由全局數據、服務(wù)函數和資源組成,在運行時(shí)被系統加載到進(jìn)程的虛擬空間中,成為調用進(jìn)程的一部分。如果與其它DLL之間沒(méi)有沖突,該文件通常映射到進(jìn)程虛擬空間的同一地址上。DLL模塊中包含各種導出函數,用于向外界提供服務(wù),Windows在加載DLL模塊時(shí)將進(jìn)程函數調用與DLL文件的導出函數相匹配。DLL可以有自己的數據段,但沒(méi)有自己的堆棧,DLL模塊需要的堆棧內存都是從運行進(jìn)程的堆棧中分配出來(lái)的,使用與調用它的應用程序相同的堆棧模式;一個(gè)DLL在內存中只有一個(gè)實(shí)例;DLL實(shí)現了代碼封裝性;DLL的編制與具體的編程語(yǔ)言及編譯器無(wú)關(guān)。

    動(dòng)態(tài)鏈接庫的分類(lèi)

    微軟的Visual C++支持三種DLL,它們分別是Non-MFC Dll(非MFC動(dòng)態(tài)庫)、Regular Dll(常規DLL)、Extension Dll(擴展DLL)。

    1、Non-MFC DLL(非MFC動(dòng)態(tài)庫)

    這種動(dòng)態(tài)鏈接庫指的是不用MFC的類(lèi)庫結構,直接用C語(yǔ)言寫(xiě)的DLL,其導出的函數是標準的C接口,能被非MFC或MFC編寫(xiě)的應用程序所調用。如果建立的DLL不需要使用MFC,那么應該建立Non-MFC DLL,因為使用MFC會(huì )增大用戶(hù)庫的大小,從而浪費用戶(hù)的磁盤(pán)和內存空間。

    2、Regular DLL(常規DLL)

    這種動(dòng)態(tài)鏈接庫和下述的Extension Dll一樣,是用MFC類(lèi)庫編寫(xiě)的,它的一個(gè)明顯的特點(diǎn)是在源文件里有一個(gè)繼承CWinApp的類(lèi)(注意:此類(lèi)DLL雖然從CWinApp派生,但沒(méi)有消息循環(huán)),被導出的函數是C函數、C++類(lèi)或者C++成員函數(注意不要把術(shù)語(yǔ)C++類(lèi)與MFC的微軟基礎C++類(lèi)相混淆),調用常規DLL的應用程序不必是MFC應用程序,只要是能調用類(lèi)C函數的應用程序就可以,它們可以是在Visual C++、Delphi、Visual Basic、Borland C等編譯環(huán)境下利用DLL開(kāi)發(fā)應用程序。常規DLL又可細分成靜態(tài)鏈接到MFC和動(dòng)態(tài)鏈接到MFC兩種:

    (1)靜態(tài)連接到MFC的動(dòng)態(tài)連接庫只被VC的專(zhuān)業(yè)般和企業(yè)版所支持。該類(lèi)DLL里的輸出函數可以被任意Win32程序使用,包括使用MFC的應用程序。輸出函數有如下形式:

    extern "C" EXPORT YourExportedFunction( );

    如果沒(méi)有extern "C"修飾,輸出函數僅僅能從C++代碼中調用。
2)動(dòng)態(tài)鏈接到MFC的常規DLL里的輸出函數可以被任意Win32程序使用,包括使用MFC的應用程序。所有從DLL輸出的函數應該以如下語(yǔ)句開(kāi)始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

    此語(yǔ)句用來(lái)正確地切換MFC模塊狀態(tài)。

    3、Extension Dll(擴展DLL)

    這種動(dòng)態(tài)鏈接庫是使用MFC的動(dòng)態(tài)鏈接版本所創(chuàng )建的,并且它只被用MFC類(lèi)庫所編寫(xiě)的應用程序所調用。例如你已經(jīng)創(chuàng )建了一個(gè)從MFC的CtoolBar類(lèi)的派生類(lèi)用于創(chuàng )建一個(gè)新的工具欄,為了導出這個(gè)類(lèi),你必須把它放到一個(gè)MFC擴展的DLL中。擴展DLL 和常規DLL不一樣,它沒(méi)有一個(gè)從CWinApp繼承而來(lái)的類(lèi)的對象,所以,開(kāi)發(fā)人員必須在DLL中的DllMain函數添加初始化代碼和結束代碼。與常規DLL相比,擴展的DLL有如下不同點(diǎn):

    1) 它沒(méi)有一個(gè)從CWinApp派生的對象;

    2) 它必須有一個(gè)DLLMain函數;

    3) DLLMain調用AfxInitExtensionModule函數,必須檢查該函數的返回值,如果返回0,DLLMmain也返回0;

    4) 如果它希望輸出CRuntimeClass類(lèi)型的對象或者資源(Resources),則需要提供一個(gè)初始化函數來(lái)創(chuàng )建一個(gè)CDynLinkLibrary對象。并且,有必要把初始化函數輸出;

    5) 使用擴展DLL的MFC應用程序必須有一個(gè)從CWinApp派生的類(lèi),而且,一般在InitInstance里調用擴展DLL的初始化函數。

    動(dòng)態(tài)連接庫的建立

    1、Non-MFC DLL的建立

    每一個(gè)DLL必須有一個(gè)入口點(diǎn),就象用C編寫(xiě)的應用程序時(shí),必須有一個(gè)WINMAIN函數一樣。在Non-MFC DLL中DllMain是一個(gè)缺省的入口函數,你不需要編寫(xiě)自己的DLL入口函數,用這個(gè)缺省的入口函數就能使動(dòng)態(tài)鏈接庫被調用時(shí)得到正確的初始化。如果應用程序的DLL需要分配額外的內存或資源,或者說(shuō)需要對每個(gè)進(jìn)程或線(xiàn)程初始化和清除操作時(shí),需要在相應的DLL工程的。CPP文件中對DllMain()函數按照下面的格式書(shū)寫(xiě)。

 BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
.......
case DLL_THREAD_ATTACH:
.......
case DLL_THREAD_DETACH:
.......
case DLL_PROCESS_DETACH:
.......
}
return TRUE;
}

 

    參數中,hMoudle是動(dòng)態(tài)庫被調用時(shí)所傳遞來(lái)的一個(gè)指向自己的句柄(實(shí)際上,它是指向_DGROUP段的一個(gè)選擇符);ul_reason_for_call是一個(gè)說(shuō)明動(dòng)態(tài)庫被調原因的標志,當進(jìn)程或線(xiàn)程裝入或卸載動(dòng)態(tài)鏈接庫的時(shí)候,操作系統調用入口函數,并說(shuō)明動(dòng)態(tài)鏈接庫被調用的原因,它所有的可能值為:

    (1)DLL_PROCESS_ATTACH: 進(jìn)程被調用或調用Load Library,DLL被鏈接到當前進(jìn)程的地址空間并被初始化;

    (2)DLL_THREAD_ATTACH: 當前進(jìn)程創(chuàng )建一個(gè)新線(xiàn)程,DLL在新線(xiàn)程正文內被調用;

    (3)DLL_PROCESS_DETACH: 調用DLL的進(jìn)程被終止,DLL被卸載;

    (4)DLL_THREAD_DETACH: 調用DLL的線(xiàn)程被終止,DLL被卸載;

    lpReserved為保留參數。

    如果在DLL中加入想要輸出的函數、變量、C++類(lèi)或其它函數,可以調用VC的關(guān)鍵字_declspec(dllexport)。

    2、MFC AppWizard[dll]方式下Regular DLL和Extension DLL的建立

    在MFC AppWizard[dll]下生成的DLL文件有三種方式:靜態(tài)鏈接到MFC的常規DLL、動(dòng)態(tài)鏈接到MFC的常規DLL以及MFC擴展DLL,在創(chuàng )建DLL是,要根據實(shí)際情況選擇創(chuàng )建DLL的方式。

    靜態(tài)鏈接到MFC的常規DLL和靜態(tài)連接到MFC常規DLL的區別是:前者使用的是MFC的靜態(tài)鏈接庫,生成的DLL文件長(cháng)度大,一般不使用這種方式;后者使用MFC的動(dòng)態(tài)鏈接庫,生成的DLL文件長(cháng)度??;動(dòng)態(tài)鏈接到MFC的常規DLL所有輸出的函數應該以如下語(yǔ)句開(kāi)始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( )) //此語(yǔ)句用來(lái)正確地切換MFC模塊狀態(tài)

    MFC擴展DLL的特點(diǎn)是用來(lái)建立MFC的派生類(lèi),Dll只被用MFC類(lèi)庫所編寫(xiě)的應用程序所調用。Extension DLLs 和Regular DLLs不一樣,它沒(méi)有一個(gè)從CWinApp繼承而來(lái)的類(lèi)的對象,編譯器默認了一個(gè)DLL入口函數DLLMain()作為對DLL的初始化,你可以在此函數中實(shí)現初始化,代碼如下:

 

 

 BOOL WINAPI APIENTRY DLLMain(HINSTANCE hinstDll,DWORD reason ,LPVOID flmpload)
{
switch(reason)
{
……………//初始化代碼;
}
return true;
}

    參數hinstDll存放DLL的句柄,參數reason指明調用函數的原因,lpReserved是一個(gè)被系統所保留的參數。對于隱式鏈接是一個(gè)非零值,對于顯式鏈接值是零。

 

    動(dòng)態(tài)連接庫的調用

    動(dòng)態(tài)鏈接庫的調用可以分為兩種:一種是隱式調用,一種是顯示調用。

    1、隱式的調用

    這種調用方式需要把產(chǎn)生動(dòng)態(tài)連接庫時(shí)產(chǎn)生的。LIB文件加入到應用程序的工程中,在使用DLL中的函數時(shí),只須說(shuō)明一下后就可以直接通過(guò)函數名調用DLL的輸出函數,調用方法和程序內部其他的函數是一樣的。隱式調用不需要調用Load Library()和Free Library()。程序員在建立一個(gè)DLL文件時(shí),鏈接程序會(huì )自動(dòng)生成一個(gè)與之對應的LIB導入文件。該文件包含了每一個(gè)DLL導出函數的符號名和可選的標識號,但是并不含有實(shí)際的代碼。LIB文件作為DLL的替代文件被編譯到應用程序項目中。

    當程序員通過(guò)隱式調用方式編譯生成應用程序時(shí),應用程序中的調用函數與LIB文件中導出符號相匹配,這些符號或標識號被寫(xiě)入到生成的EXE文件中。LIB文件中也包含了對應的DLL文件名(但不是完全的路徑名),鏈接程序也將其存儲在EXE文件內部。當應用程序運行過(guò)程中需要加載DLL文件時(shí),Windows根據這些信息發(fā)現并加載DLL,然后通過(guò)符號名或標識號實(shí)現對DLL函數的動(dòng)態(tài)鏈接。所有被應用程序調用的DLL文件都會(huì )在應用程序EXE文件加載時(shí)被加載在到內存中。

    2、顯式調用

    這種調用方式是指在應用程序中用Load Library或MFC提供的AfxLoadLibrary顯式的將自己所做的動(dòng)態(tài)連接庫調進(jìn)來(lái),并指定DLL的路徑作為參數。LoadLibary返回HINSTANCE參數,應用程序在調用GetProcAddress函數時(shí)使用這一參數。當完成對動(dòng)態(tài)鏈接庫的導入以后,再使用GetProcAddress()獲取想要引入的函數,該函數將符號名或標識號轉換為DLL內部的地址,之后就可以象使用本應用程序自定義的函數一樣來(lái)調用此引入函數了。在應用程序退出之前,應該用Free Library或MFC提供的AfxFreeLibrary釋放動(dòng)態(tài)連接庫。

    使用顯式調用方式可以讓程序員來(lái)決定DLL文件何時(shí)加載或不加載,而操作系統在載入應用程序時(shí)不必要將所有該應用程序所引用的DLL都一起加載到內存中,只要在使用某個(gè)DLL時(shí)再將其載入,這樣就可以減少應用程序在初始加載時(shí)所使用的時(shí)間和對內存的消耗。在對DLL加載的過(guò)程中,Windows將遵循下面的搜索順序來(lái)定位DLL:

    ①包含EXE文件的目錄;

    ②進(jìn)程的當前工作目錄 ;

    ③Windows系統目錄 ;

    ④Windows目錄 ;

    ⑤列在Path環(huán)境變量中的一系列目錄。

    總結

    在Windows操作系統中使用動(dòng)態(tài)鏈接庫(DLL)有很多優(yōu)點(diǎn),最主要的一點(diǎn)是多個(gè)應用程序、甚至是不同語(yǔ)言編寫(xiě)的應用程序可以共享一個(gè)DLL文件,真正實(shí)現了資源"共享",大大縮小了應用程序的執行代碼,更加有效地利用了內存;使用DLL的另一個(gè)優(yōu)點(diǎn)是DLL文件作為一個(gè)單獨的程序模塊,封裝性、獨立性好,在軟件需要升級的時(shí)候,開(kāi)發(fā)人員只需要修改相應的DLL文件就可以了,而且,當DLL中的函數改變后,如果沒(méi)有修改參數,程序代碼并不需要重新編譯。這在編程時(shí)十分有用,大大提高了軟件開(kāi)發(fā)和維護的效率。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
動(dòng)態(tài)鏈接庫創(chuàng )建與使用
VC++動(dòng)態(tài)鏈接庫編程總結一
動(dòng)態(tài)鏈接庫DLL編程(一)之簡(jiǎn)介
vc dll編程
DLL(Dynamic Link Libraries)
使用c 開(kāi)發(fā)excel插件 (第3章動(dòng)態(tài)鏈接庫(dynamic
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久