• <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>
            posts - 15, comments - 9, trackbacks - 0, articles - 0
            前幾天有個(gè)朋友問(wèn)道這個(gè)問(wèn)題,結(jié)果因?yàn)橐郧皬臎](méi)搞過(guò)這個(gè),對(duì)vs2005也不熟悉,竟花了2個(gè)小時(shí)才搞定,
            特地拿來(lái)與大家分享,希望能給像我這樣的菜鳥(niǎo)們一些幫助,O(∩_∩)O
            【第一步】創(chuàng)建自己的dll
            1.打開(kāi)vs2005,選擇菜單【File-New-Project】,在彈出對(duì)話(huà)框中選擇[Visual C++]下的[Win32]-[Win32 Console Application],輸入工程名后確認(rèn)。
            2.在彈出的對(duì)話(huà)框中選擇[next],在Application Settiongs中選擇Application type為Dll,Additional options選擇Empty project,然后點(diǎn)Finish。
            這時(shí)就創(chuàng)建了一個(gè)空的可以生成dll文件的工程。
            3.在工程中添加一個(gè)頭文件(這里為dll_test.h),在頭文件中寫(xiě)入如下內(nèi)容:
             1 #ifndef _DLL_TUTORIAL_H
             2 #define _DLL-TUTORIAL_H
             3 
             4 #include<iostream>
             5 
             6 #if defined DLL_EXPORT
             7   #define DECLDIR _declspec(dllexport)
             8 #else
             9   #define DECLDIR _declspec(dllimport)
            10 #endif
            11 
            12 extern "C"
            13 {
            14   DECLDIR int Add(int a, int b);
            15   DECLDIR void Function(void);
            16 }
            17
            18 #endif
            這里要說(shuō)明的是:
            在VC中有兩個(gè)方法來(lái)導(dǎo)出dll中定義的函數(shù):
              (1) 使用__declspec,這是一個(gè)Microsoft定義的關(guān)鍵字。
              (2) 創(chuàng)建一個(gè)模板定義文件(Module-Definition File,即.DEF)。
              第一種方法稍稍比第二種方法簡(jiǎn)單,在這里我們使用的是第一種方法。
                __declspec(dllexport)函數(shù)的作用是導(dǎo)出函數(shù)符號(hào)到在你的Dll中的一個(gè)存儲(chǔ)類(lèi)里去。
            當(dāng)下面一行被定義時(shí)我定義DECLDIR宏來(lái)運(yùn)行這個(gè)函數(shù)。
                #define DLL_EXPORT
            在此情況下你將導(dǎo)出函數(shù)Add(int a,int b)和Function().
            4.創(chuàng)建一個(gè)源文件(名字為dll_test.cpp),內(nèi)容如下:
             
            
             1 #include <iostream>
             2 #define DLL_EXPORT
             3 #include "dll_test.h"
             4 
             5 extern "C"
             6 {
             7         // 定義了(DLL中的)所有函數(shù)
             8     DECLDIR int Add( int a, int b )
             9     {
            10         return( a + b );
            11     }
            12     
            13     DECLDIR void Function( void )
            14     {
            15         std::cout << "DLL Called!" << std::endl;
            16     }
            17 }
            18 
            【第二步】使用創(chuàng)建好的DLL
            現(xiàn)在已經(jīng)創(chuàng)建了DLL,那么如何在一個(gè)應(yīng)用程序中使用它呢?
            當(dāng)DLL被生成后,它創(chuàng)建了一個(gè).dll文件和一個(gè).lib,這兩個(gè)都是使用dll時(shí)需要用到的。
            在具體介紹之前先看一下dll的鏈接方式。
            (1)隱式連接
            這里有兩個(gè)方法來(lái)載入一個(gè)DLL,一個(gè)方法是只鏈接到.lib文件,并將.dll文件放到要使用這個(gè)DLL的項(xiàng)目路徑中。
            因此,創(chuàng)建一個(gè)新的空的Win32控制臺(tái)項(xiàng)目并添加一個(gè)源文件。將我們創(chuàng)建好的DLL放入與新項(xiàng)目相同的目錄下。同時(shí)我們還必須鏈接到dll_test.lib文件。
            可以在項(xiàng)目屬性中設(shè)置,也可以在源程序中用下面的語(yǔ)句來(lái)鏈接:
            #pragma comment(lib, "dll_test.lib")
            最后,我們還要在新的win32控制臺(tái)項(xiàng)目中包含前面的dll_test.h頭文件。可以把這個(gè)頭文件放到新建win32控制臺(tái)項(xiàng)目的目錄中然后在程序中加入語(yǔ)句:
            #include "dll_test.h"
            新項(xiàng)目代碼如下:
            #include<iostream>
            #include "DLLTutorial.h"
            int main()
            {
              Function();
              std::cout<< Add(32, 56)<< endl;
              return 0;
            }
            (2)顯示鏈接
            稍微復(fù)雜一點(diǎn)的加載DLL的方法需要用到函數(shù)指針和一些Windows函數(shù)。但是,通過(guò)這種載入DLL的方法,不需要DLL的.lib文件或頭文件,而只需要DLL即可。
            下面列出一些代碼:
            /****************************************************************/
            #include <iostream>
            #include <windows.h>
            typedef int (*AddFunc)(int,int);
            typedef void (*FunctionFunc)();
            int main()
            {
            AddFunc _AddFunc;
               FunctionFunc _FunctionFunc;
               HINSTANCE hInstLibrary = LoadLibrary("DLL_Tutorial.dll");
               if (hInstLibrary == NULL)
            {
            FreeLibrary(hInstLibrary);
            }
               _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
               _FunctionFunc = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");
               if ((_AddFunc == NULL) || (_FunctionFunc == NULL))
            {
            FreeLibrary(hInstLibrary);
            }
               std::cout << _AddFunc(23, 43) << std::endl;
               _FunctionFunc();
               std::cin.get();
               FreeLibrary(hInstLibrary);
               return(1);
            }
            /*******************************************************************/
            首先可以看到,這里包括進(jìn)了windows.h頭文件,同時(shí)去掉了對(duì)dll_test.h頭文件的包含。原因很簡(jiǎn)單:因?yàn)閣indows.h包含了一些Windows函數(shù),
            它也包含了一些將會(huì)用到的Windows特定變量。可以去掉DLL的頭文件,因?yàn)楫?dāng)使用這個(gè)方法載入DLL時(shí)并不需要其頭文件。
            下面你會(huì)看到:以下面形式的一小塊古靈精怪的代碼:
                typedef int (*AddFunc)(int,int);
            typedef void (*FunctionFunc)();
                這是函數(shù)指針。因?yàn)檫@是一個(gè)關(guān)于DLL的自學(xué)指南,深入探究函數(shù)指針超出了本指南的范圍;因此,現(xiàn)在我們只把它們當(dāng)作DLL包含的函數(shù)的別名。
                我喜歡在尾部用“Func”命名之。(int,int)部分是這個(gè)函數(shù)的參數(shù)部分,比如,Add函數(shù)要獲得兩個(gè)整數(shù);因此,你需要它們
            (譯注:指(int,int)部分)作為函數(shù)指針的參數(shù)。Function函數(shù)沒(méi)有參數(shù),因此你讓它為空。main()部分中的前面兩行是聲明函數(shù)指針以使得你可
            以認(rèn)為它們等同于DLL內(nèi)部的函數(shù)。我只是喜歡預(yù)先定義它們。
                  一個(gè)HINSTANCE是一個(gè)Windows數(shù)據(jù)類(lèi)型:是一個(gè)實(shí)例的句柄;在此情況下,這個(gè)實(shí)例將是這個(gè)DLL。你可以通過(guò)使用函數(shù)LoadLibrary()獲得DLL的
            實(shí)例,它獲得一個(gè)名稱(chēng)作為參數(shù)。
                 在調(diào)用LoadLibrary函數(shù)后,你必需查看一下函數(shù)返回是否成功。你可以通過(guò)檢查HINSTANCE是否等于NULL(在Windows.h中定義為0或Windows.h包
            含的一個(gè)頭文件)來(lái)查看其是否成功。如果其等于NULL,該句柄將是無(wú)效的,并且你必需釋放這個(gè)庫(kù)。換句話(huà)說(shuō),你必需釋放DLL獲得的內(nèi)存。
                  如果函數(shù)返回成功,你的HINSTANCE就包含了指向DLL的句柄。一旦你獲得了指向DLL的句柄,你現(xiàn)在可以從DLL中重新獲得函數(shù)。
                 為了這樣作,你必須使用函數(shù)GetProcAddress(),它將DLL的句柄(你可以使用HINSTANCE)和函數(shù)的名稱(chēng)作為參數(shù)。你可以讓函數(shù)指針獲得由
            GetProcAddress()返回的值,同時(shí)你必需將GetProcAddress()轉(zhuǎn)換為那個(gè)函數(shù)定義的函數(shù)指針。舉個(gè)例子,對(duì)于Add()函數(shù),你必需將GetProcAddress()
            轉(zhuǎn)換為AddFunc;這就是它知道參數(shù)及返回值的原因。現(xiàn)在,最好先確定函數(shù)指針是否等于NULL以及它們擁有DLL的函數(shù)。
                 這只是一個(gè)簡(jiǎn)單的if語(yǔ)句;如果其中一個(gè)等于NULL,你必需如前所述釋放庫(kù)。一旦函數(shù)指針擁有DLL的函數(shù),你現(xiàn)在就可以使用它們了,但是這里有一個(gè)
            需要注意的地方:你不能使用函數(shù)的實(shí)際名稱(chēng);你必需使用函數(shù)指針來(lái)調(diào)用它們。在那以后,所有你需要做的是釋放庫(kù)如此而已。
                 現(xiàn)在你知道了DLL的一些基本知識(shí)。你知道如何創(chuàng)建它們,你也知道如何用兩種不同的方法鏈接它們。這里仍然有更多的東西需要我們學(xué)習(xí),但我把它們留給你們自己探索了和更棒的作者來(lái)寫(xiě)了。
            
            欧美精品国产综合久久| 99久久人妻无码精品系列 | 欧美久久综合九色综合| 国产伊人久久| 久久丫精品国产亚洲av| 国产精品女同一区二区久久| 亚洲&#228;v永久无码精品天堂久久| 精品综合久久久久久97| 69SEX久久精品国产麻豆| 久久人人爽人人精品视频| 国产高潮国产高潮久久久| 久久久亚洲精品蜜桃臀| 久久精品国产精品亚洲毛片 | 亚洲αv久久久噜噜噜噜噜| 国产精品18久久久久久vr| 三级韩国一区久久二区综合| AAA级久久久精品无码片| 精品久久久久久国产| 天天影视色香欲综合久久| 国产精品99久久免费观看| 色妞色综合久久夜夜| 久久成人永久免费播放| 亚洲精品国产成人99久久| 日韩AV无码久久一区二区| 国产精品久久久久久久app| 久久精品国产亚洲Aⅴ香蕉| 狠狠色丁香久久婷婷综| 人妻少妇久久中文字幕| 中文国产成人精品久久不卡| 奇米影视7777久久精品人人爽 | 久久一区二区三区免费| 久久青青草原精品影院| 久久99精品国产| www.久久热.com| 亚洲国产成人久久综合碰碰动漫3d | 狠狠色婷婷久久一区二区三区| 无码人妻久久一区二区三区蜜桃| 蜜桃麻豆www久久国产精品| 国内精品欧美久久精品| 久久国产香蕉一区精品| 亚洲国产香蕉人人爽成AV片久久|