亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Visual C++中動態鏈接庫技術淺談

2019-11-17 05:10:06
字體:
來源:轉載
供稿:網友
摘要:本文比較了Visual C++所支持的三種動態鏈接庫,列出了各自不同的特點和應用場合,具體地描述了三種動態鏈接庫的建立和調用的方法。

   要害字:動態鏈接庫;導出函數;調用

  引言

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

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

  動態鏈接庫概述

   動態鏈接庫技術是Windows最重要的實現技術之一,Windows的許多新功能、新特性都是通過DLL來實現的。其實,Windows本身就是由許多DLL組成的,它最基本的三大組成模塊Kernel、GDI和User都是DLL。

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

  動態鏈接庫的分類

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

   1、Non-MFC DLL(非MFC動態庫)

   這種動態鏈接庫指的是不用MFC的類庫結構,直接用C語言寫的DLL,其導出的函數是標準的C接口,能被非MFC或MFC編寫的應用程序所調用。假如建立的DLL不需要使用MFC,那么應該建立Non-MFC DLL,因為使用MFC會增大用戶庫的大小,從而浪費用戶的磁盤和內存空間。

   2、Regular DLL(常規DLL)

   這種動態鏈接庫和下述的Extension Dll一樣,是用MFC類庫編寫的,它的一個明顯的特點是在源文件里有一個繼續CWinApp的類(注重:此類DLL雖然從CWinApp派生,但沒有消息循環),被導出的函數是C函數、C++類或者C++成員函數(注重不要把術語C++類與MFC的微軟基礎C++類相混淆),調用常規DLL的應用程序不必是MFC應用程序,只要是能調用類C函數的應用程序就可以,它們可以是在Visual C++、Delphi、Visual Basic、Borland C等編譯環境下利用DLL開發應用程序。常規DLL又可細分成靜態鏈接到MFC和動態鏈接到MFC兩種:

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

extern "C" EXPORT YourExportedFunction( );
   假如沒有extern "C"修飾,輸出函數僅僅能從C++代碼中調用。

   (2)動態鏈接到MFC的常規DLL里的輸出函數可以被任意Win32程序使用,包括使用MFC的應用程序。所有從DLL輸出的函數應該以如下語句開始:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
   此語句用來正確地切換MFC模塊狀態。

   3、Extension Dll(擴展DLL)

   這種動態鏈接庫是使用MFC的動態鏈接版本所創建的,并且它只被用MFC類庫所編寫的應用程序所調用。例如你已經創建了一個從MFC的CtoolBar類的派生類用于創建一個新的工具欄,為了導出這個類,你必須把它放到一個MFC擴展的DLL中。擴展DLL 和常規DLL不一樣,它沒有一個從CWinApp繼續而來的類的對象,所以,開發人員必須在DLL中的DllMain函數添加初始化代碼和結束代碼。與常規DLL相比,擴展的DLL有如下不同點:

   1) 它沒有一個從CWinApp派生的對象;

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

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

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

   5) 使用擴展DLL的MFC應用程序必須有一個從CWinApp派生的類,而且,一般在InitInstance里調用擴展DLL的初始化函數。   動態連接庫的建立

   1、Non-MFC DLL的建立


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

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是動態庫被調用時所傳遞來的一個指向自己的句柄(實際上,它是指向_DGROUP段的一個選擇符);
ul_reason_for_call是一個說明動態庫被調原因的標志,當進程或線程裝入或卸載動態鏈接庫的時候,操作系統調用入口函數,并說明動態鏈接庫被調用的原因,它所有的可能值為:

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

   (2)DLL_THREAD_ATTACH: 當前進程創建一個新線程,DLL在新線程正文內被調用;

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

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

   lpReserved為保留參數。

   假如在DLL中加入想要輸出的函數、變量、C++類或其它函數,可以調用VC的要害字_declspec(dllexport)。

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

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

   靜態鏈接到MFC的常規DLL和靜態連接到MFC常規DLL的區別是:前者使用的是MFC的靜態鏈接庫,生成的DLL文件長度大,一般不使用這種方式;后者使用MFC的動態鏈接庫,生成的DLL文件長度??;動態鏈接到MFC的常規DLL所有輸出的函數應該以如下語句開始:

AFX_MANAGE_STATE(AfxGetStaticModuleState( )) //此語句用來正確地切換MFC模塊狀態

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

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

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

  動態連接庫的調用

   動態鏈接庫的調用可以分為兩種:一種是隱式調用,一種是顯示調用。

   1、隱式的調用

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

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

   2、顯式調用

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

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

   ①包含EXE文件的目錄;

   ②進程的當前工作目錄 ;

   ③Windows系統目錄 ;

   ④Windows目錄 ;

   ⑤列在Path環境變量中的一系列目錄。

  總結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
92看片淫黄大片欧美看国产片| 亚洲自拍另类欧美丝袜| 久久久影视精品| 91久久精品国产91性色| 黄色一区二区在线| 欧美天天综合色影久久精品| 日韩精品在线免费| 久久人人爽人人爽爽久久| 久久久精品国产亚洲| 日本久久亚洲电影| 91在线观看免费高清完整版在线观看| 欧美一级淫片videoshd| 成年人精品视频| 亚洲综合一区二区不卡| 国产精品久久久久影院日本| 欧美体内谢she精2性欧美| 欧美黑人一级爽快片淫片高清| 国产日韩欧美日韩| 亚洲天堂2020| 亚洲桃花岛网站| 51午夜精品视频| 视频直播国产精品| 亚洲男人天堂视频| 川上优av一区二区线观看| 国产精品一区久久| 国产精品99久久久久久白浆小说| 国产精品第三页| 日韩视频在线免费| 欧美高清在线视频观看不卡| 精品在线欧美视频| 国产一区二区三区免费视频| 欧美人成在线视频| 91在线精品播放| 2023亚洲男人天堂| 亚洲人成五月天| 日韩欧美在线观看视频| 欧美另类极品videosbest最新版本| 在线观看免费高清视频97| 国产一区视频在线播放| 久久99久久99精品中文字幕| 成人久久久久久| 成人h视频在线观看播放| 日韩免费看的电影电视剧大全| 欧美高清videos高潮hd| 欧美日韩国产精品一区| 欧美日韩精品在线视频| 久久亚洲精品毛片| 欧美日韩福利在线观看| 欧美视频在线免费看| 亚洲а∨天堂久久精品9966| 国产精品美腿一区在线看| 日韩欧美精品中文字幕| 国产精品视频精品视频| 91精品国产高清久久久久久久久| 久久99精品久久久久久琪琪| 国产一区在线播放| 亚洲综合第一页| 奇米影视亚洲狠狠色| 久久6免费高清热精品| 亚洲毛片在线看| 18一19gay欧美视频网站| 日韩欧美精品在线观看| 国产精品美女网站| 亚洲精品一区二区三区不| 欧美韩日一区二区| 性欧美视频videos6一9| 久久777国产线看观看精品| 欧洲美女7788成人免费视频| 日韩av中文字幕在线| 欧美性少妇18aaaa视频| 久久久在线免费观看| 亚洲午夜精品久久久久久久久久久久| 法国裸体一区二区| 91精品国产91久久久久久久久| 久久国产精品久久精品| 亚洲图中文字幕| 欧美电影免费播放| 亚洲色图狂野欧美| 91高清视频在线免费观看| 91大神在线播放精品| 国产极品精品在线观看| 亚洲qvod图片区电影| 欧美激情videoshd| 国产ts人妖一区二区三区| 国产欧美在线播放| 丝袜美腿亚洲一区二区| 日韩有码视频在线| 久久亚洲国产精品成人av秋霞| 91久久综合亚洲鲁鲁五月天| 高潮白浆女日韩av免费看| 久久影院中文字幕| 精品欧美国产一区二区三区| 激情成人在线视频| 91亚洲国产成人久久精品网站| 日韩精品福利网站| 国产亚洲欧美日韩一区二区| 在线观看国产精品91| 久久香蕉精品香蕉| 岛国av一区二区三区| 国产欧美日韩专区发布| 北条麻妃99精品青青久久| 亚洲欧美日韩在线高清直播| 国产中文字幕日韩| 国产精品一区专区欧美日韩| 韩国一区二区电影| 成人免费看黄网站| 国产偷亚洲偷欧美偷精品| 国产精品成人av性教育| 91久久夜色精品国产网站| 国产精品视频在线观看| 欧美高清无遮挡| 91香蕉国产在线观看| 国产精品日日摸夜夜添夜夜av| 在线观看不卡av| 欧美与欧洲交xxxx免费观看| 欧美性xxxxhd| 欧美精品一区在线播放| 在线丨暗呦小u女国产精品| 亚洲欧洲高清在线| 国产欧美日韩视频| 日韩精品中文字幕在线| 亚洲一区精品电影| 欧美激情手机在线视频| 97久久精品在线| 亚洲在线免费视频| 亚洲精品国产精品乱码不99按摩| 国产在线日韩在线| 亚洲裸体xxxx| 中日韩美女免费视频网址在线观看| 亚洲精品99久久久久| 久久视频在线看| 日本亚洲欧美成人| 国产精品色午夜在线观看| 日韩毛片中文字幕| 超在线视频97| 亚洲欧美日韩直播| 日韩av综合中文字幕| 亚洲热线99精品视频| 少妇久久久久久| 国产精品久久久久久av下载红粉| 久久精品视频在线播放| 亚洲一区二区在线播放| 久久久噜噜噜久久久| 国产美女扒开尿口久久久| 国产精品极品美女在线观看免费| 日韩a**站在线观看| 91亚洲精品在线观看| 黄色一区二区三区| 欧美精品情趣视频| 在线观看日韩欧美| 国产精品丝袜一区二区三区| 九九久久久久久久久激情| 欧美日韩国产精品一区| 国产日本欧美在线观看| 国产亚洲精品一区二555| 亚洲网在线观看| 国产精品免费久久久久影院| 国产精品久久不能| 午夜精品美女自拍福到在线| 在线视频中文亚洲| 亚洲欧美激情视频| 国产亚洲欧美另类中文| 另类专区欧美制服同性| 国产精品无码专区在线观看|