• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            動態(tài)鏈接庫,即dll -- dynamic linkable library

                    一般來說,dll是一種文件,其擴展名為.dll。它是由全局數(shù)據(jù),服務(wù)函數(shù)和資源組成;在運行的時候被加載到進程的虛擬空間中。dll中包含了各種導出函數(shù),用于向外界提供服務(wù),dll可以有自己的數(shù)據(jù)段,但是沒有自己的堆棧,它的吏用與調(diào)用它的程式有相同的堆棧模式。在win32環(huán)境中,每一個進程都復制自己的讀寫全局變量,如果要想與其它進程共享內(nèi)存,必須在聲明一個共享數(shù)據(jù)段!

                    dll也是一種可執(zhí)行文件,只不過它不能像exe文件那樣直接執(zhí)行,而是做為其它可執(zhí)行文件的共享函數(shù)庫!使用dll的應用程序可以調(diào)用dll中導出函數(shù)(imported function),不過應用程序并不包含這些函數(shù)的可執(zhí)行代碼,而是它們經(jīng)過編譯后獨立的保存在dll中!這和以前的靜態(tài)鏈接不同,使用靜態(tài)鏈接庫(static link library)的應用程序從庫中得到所引用的函數(shù)的可執(zhí)行代碼,然后放在自身的可執(zhí)行文件中,這就可使其size變大,應用程序運行不在需要靜態(tài)函數(shù)庫的支持!
                    而使用dll的應用程序只包含用于dll中定位所引用的函數(shù)信息,沒有函數(shù)的實現(xiàn),其size相對靜態(tài)要小的多,但是其運行要從dll中獲得函數(shù)的實現(xiàn)代碼,要dll的支持!


                    dll的優(yōu)點:
                    1. dll提供一種共享數(shù)據(jù)和代碼的途徑,由于多個應用程序共享同一個dll中的函數(shù),可以縮小應用程式的可執(zhí)行文件的大小,使的dll可以顯著的節(jié)省磁盤空間。
                    2. dll是獨立于可執(zhí)行文件的,如果要向dll中增加新的函數(shù)和功能,只要原有函數(shù)的參數(shù)和返回值不變,所有使用這個dll的應用程序升級后都不要重新編譯。
                    3. 標準的dll可以被其它語言來使用! 

                    dll有多種類型,非 MFC dll,靜態(tài)鏈接到MFC的常規(guī)dll,動態(tài)鏈接到MFC的常規(guī)dll. MFC 擴展dll。dll文件包括一個導出表,導出表中給出可從dll中導出函數(shù)的名字,dll中定義了兩種函數(shù),導出函數(shù)(export function)和內(nèi)部函數(shù)(internal function),其中導出函數(shù)可以被其它的模塊調(diào)用,而內(nèi)部函數(shù)只能在內(nèi)部使用。dll結(jié)構(gòu)可以用VC++工具dumpbin和depends查看!

                    編寫dll的主要步驟
                    我們在用C++定制dll文件時,要編寫包含導出函數(shù)的模塊定義文件.def和實現(xiàn)導出函數(shù)功能的C++文件。
                    1. 模塊定義文件(.def)是由一個或者多個用于描述dll屬性的語句塊組成的文本文件,每個.def文件必須包含以下模塊定義語句。
                    第一個語句必須是LIBRARY語句,其指出dll的名字。
                    第二個EXPORTS語句列出被導出函數(shù)的名字,";"對一行進行注釋!
                     LIBRARY mydll
                     EXPORTS
                     ulDataInDll   DATA

                     myfunction @number
                     其中@number指出導出函數(shù)的順序值。
                    2. 實現(xiàn)文件,在入口表函數(shù)的.cpp文件中,包含dll入口點處理的API函數(shù)和導出函數(shù)的代碼。入口函數(shù)LibMain()就像C中的main(),windows每次加載dll時都要執(zhí)行此函數(shù)。

            dll中函數(shù)導出的方法有兩種,1. 在創(chuàng)建dll時使用.DEF文件。2. 在定義函數(shù)時使用關(guān)鍵字_declspec(dllexport)。僅僅知道導出數(shù)的名稱并不足以從dll中導出函數(shù)。若在應用程序中使用顯式鏈接,至少還要知道導出函數(shù)的返回值及參數(shù)。若用隱函鏈接,必須括有導出函數(shù)的定義頭文件(.h) 和  引入庫文件(import library, .LIB文件)。

                    如。1使用DEF文件導出DLL中的函數(shù)。
                    prog.DEF文件定義一個函數(shù)。

                    LIBRARY mydll
                    EXPORTS

                    ShowMsgBox      @1

                    頭文件showmsgbox.h
                    #include <windows>
                    extern "C"
                    {
                         int ShowMsgBox(LPCTSTR lpText = 'example', LPCTSTR lpCaption = 'EXAMPLE');
                    }

                    實現(xiàn)文件showmsgbox.cpp
                    #include "showmsgbox.h"
                    int ShowMsgBox(LPCTSTR lpText = 'example', LPCTSTR lpCaption = 'EXAMPLE')
                    {
                         return MessageBox(NULL, lpText, lpCaption);
                    }
                    然后編譯后生成showmsgbox.lib, showmsgbox.dll.

                    2. 使用_declspec(dllexport)導出dll中的函數(shù),此時不用DEF文件。
                    頭文件showmsgbox.h
                    #include <windows>
                    extern "C"
                    {
                         _declspec(dllexport) int ShowMsgBox(LPCTSTR lpText = 'example', LPCTSTR lpCaption = 'EXAMPLE');
                    }
                    .cpp文件還是上面那個,然后編譯后生成showmsgbox.lib, showmsgbox.dll.

                   dll加載與調(diào)用
                   dll加載順序,1. 系統(tǒng)dll,如kennel32.dll, user32.dll  2. 工作盤當前目錄 3. windows系統(tǒng)目錄,用GetsystemDirectory()可以獲得。4. windows所在目錄。

                    dll有兩種調(diào)用方法,靜態(tài)調(diào)用,動態(tài)調(diào)用。靜態(tài)調(diào)用是編譯系統(tǒng)完成加載dll和應用程序結(jié)束時卸載dll,這種方法簡單但不靈活。動態(tài)調(diào)用方式使用API加載卸載dll。
                    隱含鏈接,顯式鏈接
                    隱含鏈接要dll文件外還要一個包含導出函數(shù)或C++類頭文件和相應的LIB
                    showmsgbox.dll對應的頭文件showmsgbox.h
                    #include <windows.h>
                    extern "C"
                    {
                         _declspec(dllimport) int ShowMsgBox(LPCTSTR lpText = 'example', LPCTSTR lpCaption = 'EXAMPLE');
                    }
                    使不使用_declspec(dllimport)都可以,但是使用它會產(chǎn)生更高效的代碼。
                    dlltest.cpp
                    #include "showmsgbox.h"
                    int _stdcall winmain(......)
                   {
                         return ShowMsgBox();
                   }
             然后把showmsgbox.dll文件放到工程的debug\下,同時把showmsgbox.LIB放到鏈接器的命令行中。就OK了!!
                     
                    顯式鏈接
                    用API加載dll,LoadLibrary() --> GetProcAddress() --> FreeLibrary().
                    dlltest.cpp
                    #include <windows>
                    typedef (callback *DLLFUNC)(LPCTSTR lpText = 'example', LPCTSTR lpCaption = 'EXAMPLE');
                    int _stdcall winmain(......)
                   {
                         HINSTANCE hDll; //DLL句柄
                            DLLFUNC  ShowMsgBox; //函數(shù)指針
                            hDll = LoadLibrary("mydll');
                         if (hDLL != NULL)
                         {
                              ShowMsgBox = (DLLFUNC)GetProcAddress(hDll, "mydll");
                         }
                            FreeLibrary(hDLL);
                  }
                  OK!
                   
            1、靜態(tài)調(diào)用方式:由編譯系統(tǒng)完成對DLL的加載和應用程序結(jié)束時DLL卸載的編碼(如還有其它程序使用該DLL,則Windows對DLL的應用記錄減1,直到所有相關(guān)程序都結(jié)束對該DLL的使用時才釋放它),簡單實用,但不夠靈活,只能滿足一般要求。  
               
                隱式的調(diào)用:需要把產(chǎn)生動態(tài)連接庫時產(chǎn)生的.LIB文件加入到應用程序的工程中,想使用DLL中的函數(shù)時,只須說明一下。隱式調(diào)用不需要調(diào)用LoadLibrary()和FreeLibrary()。程序員在建立一個DLL文件時,鏈接程序會自動生成一個與之對應的LIB導入文件。該文件包含了每一個DLL導出函數(shù)的符號名和可選的標識號,但是并不含有實際的代碼。LIB文件作為DLL的替代文件被編譯到應用程序項目中。當程序員通過靜態(tài)鏈接方式編譯生成應用程序時,應用程序中的調(diào)用函數(shù)與LIB文件中導出符號相匹配,這些符號或標識號進入到生成的EXE文件中。LIB文件中也包含了對應的DLL文件名(但不是完全的路徑名),鏈接程序?qū)⑵浯鎯υ贓XE文件內(nèi)部。當應用程序運行過程中需要加載DLL文件時,Windows根據(jù)這些信息發(fā)現(xiàn)并加載DLL,然后通過符號名或標識號實現(xiàn)對DLL函數(shù)的動態(tài)鏈接。所有被應用程序調(diào)用的DLL文件都會在應用程序EXE文件加載時被加載在到內(nèi)存中。可執(zhí)行程序鏈接到一個包含DLL輸出函數(shù)信息的輸入庫文件(.LIB文件)。操作系統(tǒng)在加載使用可執(zhí)行程序時加載DLL。可執(zhí)行程序直接通過函數(shù)名調(diào)用DLL的輸出函數(shù),調(diào)用方法和程序內(nèi)部其他的函數(shù)是一樣的。  
               
               
              2、動態(tài)調(diào)用方式:是由編程者用API函數(shù)加載和卸載DLL來達到調(diào)用DLL的目的,使用上較復雜,但能更加有效地使用內(nèi)存,是編制大型應用程序時的重要方式。  
               
                顯式的調(diào)用:是指在應用程序中用LoadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動態(tài)連接庫調(diào)進來,動態(tài)連接庫的文件名即是上面兩個函數(shù)的參數(shù),再用GetProcAddress()獲取想要引入的函數(shù)。自此,你就可以象使用如同本應用程序自定義的函數(shù)一樣來調(diào)用此引入函數(shù)了。在應用程序退出之前,應該用FreeLibrary或MFC提供的AfxFreeLibrary釋放動態(tài)連接庫。直接調(diào)用Win32   的LoadLibary函數(shù),并指定DLL的路徑作為參數(shù)。LoadLibary返回HINSTANCE參數(shù),應用程序在調(diào)用GetProcAddress函數(shù)時使用這一參數(shù)。GetProcAddress函數(shù)將符號名或標識號轉(zhuǎn)換為DLL內(nèi)部的地址。程序員可以決定DLL文件何時加載或不加載,顯式鏈接在運行時決定加載哪個DLL文件。使用DLL的程序在使用之前必須加載(LoadLibrary)加載DLL從而得到一個DLL模塊的句柄,然后調(diào)用GetProcAddress函數(shù)得到輸出函數(shù)的指針,在退出之前必須卸載DLL(FreeLibrary)。  
               
                      Windows將遵循下面的搜索順序來定位DLL:    
              1.包含EXE文件的目錄,    
              2.進程的當前工作目錄,    
              3.Windows系統(tǒng)目錄,    
              4.Windows目錄,    
              5.列在Path環(huán)境變量中的一系列目錄。
            一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 亚洲日本va中文字幕久久| 欧美激情精品久久久久久久 | 久久夜色精品国产www| 99久久综合国产精品免费| 欧美亚洲色综久久精品国产| 99久久777色| 色综合久久88色综合天天 | 亚洲愉拍99热成人精品热久久| 99久久国产综合精品麻豆| 久久久久国产精品麻豆AR影院 | 亚洲国产成人久久笫一页| 久久99精品国产麻豆| 久久天天躁狠狠躁夜夜2020| 亚洲精品无码久久久久久| 国内精品久久久久久久影视麻豆| 精品国产乱码久久久久久人妻| 一本大道久久a久久精品综合| 久久青青色综合| 久久免费视频一区| 久久久国产精品网站| 午夜天堂精品久久久久| 亚洲国产日韩综合久久精品| 国产L精品国产亚洲区久久| 国内精品久久人妻互换| 精品综合久久久久久98| 人人狠狠综合久久亚洲高清| 久久精品一区二区国产| 久久无码人妻一区二区三区 | 无码国内精品久久综合88| 久久久久婷婷| 精品无码久久久久久久动漫| 久久亚洲国产欧洲精品一| 久久99精品久久久久久hb无码 | 国产午夜电影久久| 97久久精品人人澡人人爽| 精品久久久久久成人AV| 久久99热只有频精品8| 精品久久久久久无码专区| 久久久久免费看成人影片| 久久精品水蜜桃av综合天堂|