• <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>

            C++ Programmer

            天行健,君子以自強(qiáng)不息; 地勢坤,君子以厚德載物

            DLL入門淺析(2)——如何使用DLL

            上文我簡單的介紹了如何建立一個(gè)簡單DLL,下面再我簡單的介紹一下如何使用一個(gè)DLL。當(dāng)一個(gè)DLL被生成后,它創(chuàng)建了一個(gè).dll文件和一個(gè).lib文件;這兩個(gè)都是你需要的。要使用DLL,就需要載入這個(gè)DLL。

            隱式鏈接

            這里有兩個(gè)方法來載入一個(gè)DLL;一個(gè)方法是捷徑另一個(gè)則相比要復(fù)雜些。捷徑是只鏈接到你.lib 文件并將.dll文件置入你的新項(xiàng)目的路徑中去。因此,創(chuàng)建一個(gè)新的空的Win32控制臺(tái)項(xiàng)目并添加一個(gè)源文件。將你做的DLL放入你的新項(xiàng)目相同的目錄下。

            #include "stdafx.h"
            #include 
            "DLLSample.h"

            #pragma comment(lib, 
            "DLLSample.lib"//你也可以在項(xiàng)目屬性中設(shè)置庫的鏈接

            int main()
            {
                    TestDLL(
            123);
                    
            return(1);
            }

            這就是載入一個(gè)DLL的簡單方法。

            顯式鏈接

            難點(diǎn)的加載DLL的方法稍微有點(diǎn)復(fù)雜。你將需要函數(shù)指針和一些Windows函數(shù)。但是,通過這種載入DLLs的方法,你不需要DLL的.lib或頭文件,而只需要DLL。

            #include <iostream>
            #include 
            <windows.h>
            typedef 
            void (*DLLFunc)(int);
            int main()
            {
                    DLLFunc dllFunc;
                    HINSTANCE hInstLibrary 
            = LoadLibrary("DLLSample.dll");

                    
            if (hInstLibrary == NULL)
                    
            {
                     FreeLibrary(hInstLibrary);
                    }

                    dllFunc 
            = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL");
                    
            if (dllFunc == NULL)
                    
            {
                     FreeLibrary(hInstLibrary);
                    }

                    dllFunc(
            123);
                    std::cin.
            get();
                    FreeLibrary(hInstLibrary);
                    
            return(1);
            }

                 
            首先你會(huì)注意到:這里包括進(jìn)了文件“windows.h”同時(shí)移走了“DLLSample.h”。原因很簡單:因?yàn)閣indows.h包含了一些Windows函數(shù),當(dāng)然你現(xiàn)在將只需要其中幾個(gè)而已。它也包含了一些將會(huì)用到的Windows特定變量。你可以去掉DLL的頭文件(DLLSample.h)因?yàn)椋缥仪懊嫠f-當(dāng)你使用這個(gè)方法載入DLL時(shí)你并不需要它。

            下面你會(huì)看到:下面的一句代碼:

            typedef void (*DLLFunc)(int);
                 
            這是一個(gè)函數(shù)指針類型的定義。指向一個(gè)函數(shù)是一個(gè)int型的參數(shù),返回值為void類型。

            一個(gè)HINSTANCE是一個(gè)Windows數(shù)據(jù)類型:是一個(gè)實(shí)例的句柄;在此情況下,這個(gè)實(shí)例將是這個(gè)DLL。你可以通過使用函數(shù)LoadLibrary()獲得DLL的實(shí)例,它獲得一個(gè)名稱作為參數(shù)。在調(diào)用LoadLibrary函數(shù)后,你必需查看一下函數(shù)返回是否成功。你可以通過檢查HINSTANCE是否等于NULL(在Windows.h中定義為0或Windows.h包含的一個(gè)頭文件)來查看其是否成功。如果其等于NULL,該句柄將是無效的,并且你必需釋放這個(gè)庫。換句話說,你必需釋放DLL獲得的內(nèi)存。如果函數(shù)返回成功,你的HINSTANCE就包含了指向DLL的句柄。

            一旦你獲得了指向DLL的句柄,你現(xiàn)在可以從DLL中重新獲得函數(shù)。為了這樣作,你必須使用函數(shù)GetProcAddress(),它將DLL的句柄(你可以使用HINSTANCE)和函數(shù)的名稱作為參數(shù)。你可以讓函數(shù)指針獲得由GetProcAddress()返回的值,同時(shí)你必需將GetProcAddress()轉(zhuǎn)換為那個(gè)函數(shù)定義的函數(shù)指針。舉個(gè)例子,對于Add()函數(shù),你必需將GetProcAddress()轉(zhuǎn)換為AddFunc;這就是它知道參數(shù)及返回值的原因。現(xiàn)在,最好先確定函數(shù)指針是否等于NULL以及它們擁有DLL的函數(shù)。這只是一個(gè)簡單的if語句;如果其中一個(gè)等于NULL,你必需如前所述釋放庫。

            一旦函數(shù)指針擁有DLL的函數(shù),你現(xiàn)在就可以使用它們了,但是這里有一個(gè)需要注意的地方:你不能使用函數(shù)的實(shí)際名稱;你必需使用函數(shù)指針來調(diào)用它們。在那以后,所有你需要做的是釋放庫如此而已。

            模塊句柄

            進(jìn)程中的每個(gè)DLL模塊被全局唯一的32字節(jié)的HINSTANCE句柄標(biāo)識(shí)。進(jìn)程自己還有一個(gè)HINSTANCE句柄。所有這些模塊句柄都只有在特定的進(jìn)程內(nèi)部有效,它們代表了DLL或EXE模塊在進(jìn)程虛擬空間中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,這個(gè)兩種類型可以替換使用。進(jìn)程模塊句柄幾乎總是等于0x400000,而DLL模塊的加載地址的缺省句柄是0x10000000。如果程序同時(shí)使用了幾個(gè)DLL模塊,每一個(gè)都會(huì)有不同的HINSTANCE值。這是因?yàn)樵趧?chuàng)建DLL文件時(shí)指定了不同的基地址,或者是因?yàn)榧虞d程序?qū)LL代碼進(jìn)行了重定位。
            模塊句柄對于加載資源特別重要。Win32 的FindResource函數(shù)中帶有一個(gè)HINSTANCE參數(shù)。EXE和DLL都有其自己的資源。如果應(yīng)用程序需要來自于DLL的資源,就將此參數(shù)指定為DLL的模塊句柄。如果需要EXE文件中包含的資源,就指定EXE的模塊句柄。
            但是在使用這些句柄之前存在一個(gè)問題,你怎樣得到它們呢?如果需要得到EXE模塊句柄,調(diào)用帶有Null參數(shù)的Win32函數(shù)GetModuleHandle;如果需要DLL模塊句柄,就調(diào)用以DLL文件名為參數(shù)的Win32函數(shù)GetModuleHandle。

            應(yīng)用程序怎樣找到DLL文件

            如果應(yīng)用程序使用LoadLibrary顯式鏈接,那么在這個(gè)函數(shù)的參數(shù)中可以指定DLL文件的完整路徑。如果不指定路徑,或是進(jìn)行隱式鏈接,Windows將遵循下面的搜索順序來定位DLL:
            1. 包含EXE文件的目錄,
            2. 進(jìn)程的當(dāng)前工作目錄,
            3. Windows系統(tǒng)目錄,
            4. Windows目錄,
            5. 列在Path環(huán)境變量中的一系列目錄。
            這里有一個(gè)很容易發(fā)生錯(cuò)誤的陷阱。如果你使用VC++進(jìn)行項(xiàng)目開發(fā),并且為DLL模塊專門創(chuàng)建了一個(gè)項(xiàng)目,然后將生成的DLL文件拷貝到系統(tǒng)目錄下,從應(yīng)用程序中調(diào)用DLL模塊。到目前為止,一切正常。接下來對DLL模塊做了一些修改后重新生成了新的DLL文件,但你忘記將新的DLL文件拷貝到系統(tǒng)目錄下。下一次當(dāng)你運(yùn)行應(yīng)用程序時(shí),它仍加載了老版本的DLL文件,這可要當(dāng)心!

            調(diào)試DLL程序

            Microsoft 的VC++是開發(fā)和測試DLL的有效工具,只需從DLL項(xiàng)目中運(yùn)行調(diào)試程序即可。當(dāng)你第一次這樣操作時(shí),調(diào)試程序會(huì)向你詢問EXE文件的路徑。此后每次在調(diào)試程序中運(yùn)行DLL時(shí),調(diào)試程序會(huì)自動(dòng)加載該EXE文件。然后該EXE文件用上面的搜索序列發(fā)現(xiàn)DLL文件,這意味著你必須設(shè)置Path環(huán)境變量讓其包含DLL文件的磁盤路徑,或者也可以將DLL文件拷貝到搜索序列中的目錄路徑下。
            或者當(dāng)你調(diào)試EXE程序時(shí),在Project Setting中,將Debug選項(xiàng)卡中的Category設(shè)置為Additional DLLs。就可以同時(shí)調(diào)試EXE和它調(diào)用的DLL(當(dāng)然,你需要有DLL的源代碼)了。
               

            posted on 2009-07-20 14:27 Saga 閱讀(9699) 評論(1)  編輯 收藏 引用 所屬分類: Windows

            評論

            # re: DLL入門淺析(2)——如何使用DLL 2009-07-20 20:00 羅萊家紡

            學(xué)東西了??!  回復(fù)  更多評論   

            導(dǎo)航

            <2009年7月>
            2829301234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲欧美日韩久久精品| 三级片免费观看久久| 2021久久国自产拍精品| 久久精品www人人爽人人| 久久青青草原精品影院| 久久中文精品无码中文字幕| 成人午夜精品无码区久久| 久久这里只精品国产99热| 久久中文字幕精品| 精品久久综合1区2区3区激情| 久久久久久亚洲精品不卡 | 久久精品国产一区二区三区不卡| 久久久久无码专区亚洲av| 午夜久久久久久禁播电影| 精品久久久久久国产牛牛app| 国产成人精品久久| 狠狠久久综合| 国产精品久久久久久久| 色婷婷久久综合中文久久蜜桃av| 欧美日韩精品久久久免费观看 | 无码精品久久久天天影视| 国产精品嫩草影院久久| 2022年国产精品久久久久| 一本一道久久综合狠狠老 | 久久精品一区二区三区中文字幕 | 成人精品一区二区久久| 一本一道久久综合狠狠老| 手机看片久久高清国产日韩| 18岁日韩内射颜射午夜久久成人| 久久久久久国产精品无码超碰| 久久99热这里只有精品66| 久久亚洲2019中文字幕| 国产精品亚洲综合专区片高清久久久| 精品永久久福利一区二区| 无码人妻精品一区二区三区久久久 | 91秦先生久久久久久久| 久久亚洲国产精品一区二区| 97久久精品国产精品青草| 99久久人妻无码精品系列蜜桃| 国产成人精品白浆久久69| 国产精品久久久久9999高清|