免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
《windows核心編程系列》十七談?wù)刣ll

DLL全稱dynamic linking library.即動態(tài)鏈接庫。廣泛應(yīng)用與windows及其他系統(tǒng)中。因此對dll的深刻了解,對計算機(jī)軟件開發(fā)專業(yè)人員來說非常重要。

  windows中所有API都包含在DLL中。三個最重要的DLL是Kernel32.dll,User32.dll,GDI32.dll。

      使用dll的好處:

     1:擴(kuò)展了應(yīng)用程序的特性。

     2:簡化了項(xiàng)目管理

          可以讓不同的開發(fā)團(tuán)隊管理不同的模塊。

     3:有助于節(jié)省內(nèi)存。

          一個dll可被多個程序共享。多個程序調(diào)用同一個dll內(nèi)的同一個函數(shù)時,系統(tǒng)卻只需將該dll加載一次。

    4:促進(jìn)資源共享。

    5:促進(jìn)了本地化

         可以使應(yīng)用程序只包含代碼但不包含用戶界面組件。

    6:有助于解決平臺間差異。

        使用延遲加載機(jī)制,程序僅僅加載需要的函數(shù),使程序可以在老版本的系統(tǒng)中運(yùn)行,可不是在某些函數(shù)不被兼容時拒絕運(yùn)行。

     7:可以用于特殊目的。

          如鉤子等等。

          在應(yīng)用程序可以調(diào)用dll中的函數(shù)之前,必須將dll載入進(jìn)程地址空間??梢酝ㄟ^兩種方式實(shí)現(xiàn):一種是通過隱式載入時鏈接。另一種是顯式運(yùn)行時鏈接。接下來主要介紹隱式鏈接的過程。顯式鏈接在DLL高級技術(shù)中介紹。

     在載入之前,必須要構(gòu)造DLL文件。下面我們來談?wù)刣ll的構(gòu)造過程。

      1:創(chuàng)建一個頭文件。該頭文件包含我們想要在dll中導(dǎo)出的函數(shù)原型、結(jié)構(gòu)以及符號。構(gòu)建dll時所有的源文件都必須包含該頭文件。另外可執(zhí)行文件也需要該頭文件。

      2:創(chuàng)建源文件來實(shí)現(xiàn)dll模塊中想要導(dǎo)出的函數(shù)和變量。該源文件在構(gòu)造可執(zhí)行文件時并需要該源文件。

      3:編譯器對每個源文件處理,并分別產(chǎn)生一個obj文件。

      4:鏈接所有的obj模塊。產(chǎn)生獨(dú)立的dll映像文件。該文件在構(gòu)建可執(zhí)行文件時被使用。

      5:如果dll文件中輸出了至少一個函數(shù)或變量,鏈接器還會生成lib文件。他只是列出了所有被導(dǎo)出的函數(shù)和變量的符號名。為了構(gòu)建可執(zhí)行模塊,在可執(zhí)行模塊代鏈接時,該文件也是必需的。

 構(gòu)建可執(zhí)行模塊

        1:所有源文件中包含dll開發(fā)人員創(chuàng)建的dll的頭文件。

        2:創(chuàng)建源文件。包含所有函數(shù)和變量。代碼中可以引用dll的函數(shù)和變量。

        3:為每個源文件產(chǎn)生obj文件。

        4:將所有obj文件鏈接,生成獨(dú)立的可執(zhí)行映像文件。該文件中包含所有二進(jìn)制代碼預(yù)計全局靜態(tài)變量。還包含一個導(dǎo)入段,列出了他需要的dll模塊的名稱,以及可執(zhí)行文件的二進(jìn)制代碼從中引用的函數(shù)和變量的符號名。

執(zhí)行:

        加載程序?yàn)樾陆ㄟM(jìn)程申請一個地址空間區(qū)域,然后將可執(zhí)行模塊映射到地址空間中。加載程序解釋exe文件的導(dǎo)入段,對導(dǎo)入段中每個導(dǎo)入函數(shù)所在的dll,加載程序會在系統(tǒng)中對dll模塊進(jìn)行定位,并將該dll映射到進(jìn)程的地址空間中。如果dll需要從其他dll導(dǎo)入變量或函數(shù),其他dll也會被映射到進(jìn)程地址空間,執(zhí)行類似的操作。將所有dll映射到進(jìn)程地址空間后,就可以開始運(yùn)行了。

構(gòu)建dll模塊。

        dll中通常只包含函數(shù)或變量,并不包含消息循環(huán)或創(chuàng)建窗口的代碼,因此創(chuàng)建dll文件相對容易。要注意在實(shí)際使用中,為了去掉代碼的抽象層,應(yīng)該避免從dll中導(dǎo)出變量。

        首先應(yīng)該創(chuàng)建一個包含想要導(dǎo)出的變量或函數(shù)聲明的頭文件。所有dll的源文件都應(yīng)該包含這個文件,所有需要導(dǎo)入這些函數(shù)和變量的可執(zhí)行模塊的源文件也要包含該文件。

    看例子:

     

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  2.   
  3.      //Mydll.h   dll頭文件。  
  4.   
  5.      #ifndef MYLIBAPI  
  6.   
  7.    
  8.   
  9.      #define MYLIBAPI extern"C" _declspec(dellimport)//用于可執(zhí)行模塊。  
  10.   
  11.      #endif  
  12.   
  13.      MYLIBAPI      export_variable;  
  14.   
  15.      MYLIBAPI   int  export_func();  
  16.   
  17.     dll源文件   
  18.   
  19. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  20.   
  21.        #define MYLIBAPI   extern"C"     _declspec(dllexport)  
  22.   
  23.                              //如果編譯器看到一個變量函數(shù)或是C++類是使用  
  24.   
  25.                              //此修飾符修飾的,他就知道應(yīng)該在dll模塊中導(dǎo)出該變量。external “C”不要漏掉哦?。?!  
  26.   
  27.                              //另外要注意,在dll的頭文件中,MYLIBAPI一定要在包含dll的  
  28.   
  29.                              //頭文件之前定義  
  30.   
  31.                              //否則預(yù)處理器就會因?yàn)槲炊xMYLIBAPI而將  
  32.   
  33.                              //MYLIBAPI定義為_desclspec(import)  
  34.   
  35.       #include "Mydll.h"                                                                         
  36.   
  37.       int export_varibale;    
  38.   
  39.                            //在源文件中的變量定義時,可以不使用_declspec(dllexport)修飾符,  
  40.   
  41.                           //因?yàn)榫幾g器在解析頭文件時會記住應(yīng)該導(dǎo)出那些函數(shù)或變量。  
  42.   
  43.      int export_func( int a)  
  44.   
  45.     {  
  46.   
  47.          a++;  
  48.   
  49.         return a;  
  50.   
  51.     }  
  52.   
  53. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////  


 

           可以看到在dll的頭文件中使用條件編譯#ifdef,對是否在源文件中對MYLIBAPI定義進(jìn)行了判斷。如果沒有定義的話就定義它為_declspec(import),這主要是在可執(zhí)行文件源文件中使用,目的是告訴編譯器應(yīng)該導(dǎo)入哪些符號或函數(shù)。這樣在需要引用該dll的可執(zhí)行模塊實(shí)現(xiàn)文件中就可以不定義_declspec(import).

          代碼中出現(xiàn)了extern"C"修飾符,只有在編寫C++代碼時才應(yīng)該使用該修飾符。因?yàn)镃++編譯器會對函數(shù)名和變量名進(jìn)行改編,而C語言或其他語言不對變量名和函數(shù)名進(jìn)行改編。如果在創(chuàng)建dll的時候使用C++語言實(shí)現(xiàn),編譯器對函數(shù)名進(jìn)行了改編,而可執(zhí)行文件使用c語言實(shí)現(xiàn)的。當(dāng)可執(zhí)行文件引用dll中的變量或函數(shù)時,在鏈接時就會發(fā)現(xiàn)可執(zhí)行文件引用了一個不存在的符號。通過在C++源代碼中使用extern"C“修飾符,就告訴C++編譯器不要對函數(shù)或變量名進(jìn)行改編處理。這樣用C,C++或是任何語言編寫的可執(zhí)行模塊都可以訪問該變量或函數(shù)。

           在鏈接dll的時候,鏈接器如果發(fā)現(xiàn)有函數(shù)或變量被導(dǎo)出,就會生成一個lib文件,該文件列出了該dll導(dǎo)出的符號。在鏈接任何可執(zhí)行模塊的時候只要可執(zhí)行模塊引用了該dll導(dǎo)出的符號,那么這個lib文件當(dāng)然是必須的。除了產(chǎn)生這個lib文件之外,在dll文件中還會被嵌入一個導(dǎo)出符號表。被稱為導(dǎo)入段,它列出了導(dǎo)出的變量、函數(shù)、和類的符號名,還會保存虛擬地址RVA,表示每個符號可以再dll的何處找到。

   構(gòu)建可執(zhí)行模塊

    

  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  2.   
  3.    //源文件  
  4.   
  5.     #include<iostream.h>  
  6.   
  7.     #include"Myldll.h"  
  8.   
  9.      //在此文件內(nèi)不應(yīng)該定義MYLIBAPI,在MYdll.h會檢測到,然后將MYLIBAPI定義為  
  10.   
  11.      //_declspect(import),當(dāng)編譯器檢測到源文件中某個變量或是函數(shù)使用該修飾符修飾時,  
  12.   
  13.      //他會知道應(yīng)該從某個dll導(dǎo)入該符號。另外可以不使用該修飾符,但是使用該修飾符會產(chǎn)生  
  14.   
  15.      //略微高效的代碼。所以建議使用。   
  16.   
  17.       #pragma comment(lib,"MyIdlll.lib")//不能省略哦,否則將會導(dǎo)致連接錯誤?。。。。。?nbsp; 
  18.   
  19.     int main(int argc,char**argv)  
  20.   
  21.    {  
  22.   
  23.        int a=4;  
  24.   
  25.        a=export_fucn(a);  
  26.   
  27.       std::cout<<a<<std::endl;  
  28.   
  29.    }  
  30.   
  31. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  


 

           要想使該可執(zhí)行模塊源文件鏈接成功,還必須提供Mydll生成的lib文件。由于鏈接器需要將所有的obj文件鏈接到一起,它必須確定代碼中的哪個符號來自哪個dll,提供所有使用到的dll生成的lib文件是必須的。可用在客戶代碼中使用#pragma comment(lib,"../dll.lib")如果所有的符號都能被解決,那么將會生成可執(zhí)行模塊。

 運(yùn)行可執(zhí)行模塊:
          前面我們提過,啟動一個可執(zhí)行模塊時,系統(tǒng)加載程序會為進(jìn)程申請一塊地址空間,接著將可執(zhí)行文件模塊映射到進(jìn)程地址空間中,然后檢查可執(zhí)行文件的導(dǎo)入段,將所需的dll進(jìn)行定位并將它們映射到進(jìn)程的地址空間中。

由于導(dǎo)入段不包含路徑只包含名稱,所以將在程序必須按照特定的目錄搜索DLL文件。

          以下是加載程序的搜索順序:

          1:可執(zhí)行文件目錄。

          2:windows系統(tǒng)目錄。

          3:windows目錄的System目錄。

          4:windows目錄。

          5:進(jìn)程當(dāng)前目錄。

          6:PATH環(huán)境變量所列出的目錄。

           為了防止DLL偽造,windows進(jìn)行了設(shè)定,使對對windows目錄的搜索先于應(yīng)用程序的當(dāng)前目錄。此設(shè)置可以通過改變注冊表進(jìn)行改變。

          更多關(guān)于dll的信息請參考另一篇博文:談?wù)刣ll高級技術(shù)。 

           參考自《windows核心編程》第五版第四部分,以上僅僅是個人總結(jié),如有紕漏,請不吝賜教。

  
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
DLL基礎(chǔ)
extern “C”和
DLL入門淺析
PE文件結(jié)構(gòu)詳解(六)重定位
code guy的自我修養(yǎng) | 隨緣
C基礎(chǔ)語法梳理:Windows的動態(tài)鏈接庫
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服