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

            如何創建自己的dll

            Posted on 2009-04-28 12:10 沙漠里的海豚 閱讀(495) 評論(0)  編輯 收藏 引用 所屬分類: c/c++標準
            前幾天有個朋友問道這個問題,結果因為以前從沒搞過這個,對vs2005也不熟悉,竟花了2個小時才搞定,。
            特地拿來與大家分享,希望能給像我這樣的菜鳥們一些幫助,O(∩_∩)O
            【第一步】創建自己的dll
            1.打開vs2005,選擇菜單【File-New-Project】,在彈出對話框中選擇[Visual C++]下的[Win32]-[Win32 Console Application],輸入工程名后確認。
            2.在彈出的對話框中選擇[next],在Application Settiongs中選擇Application type為Dll,Additional options選擇Empty project,然后點Finish。
            這時就創建了一個空的可以生成dll文件的工程。
            3.在工程中添加一個頭文件(這里為dll_test.h),在頭文件中寫入如下內容:
             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
            這里要說明的是:
            在VC中有兩個方法來導出dll中定義的函數:
              (1) 使用__declspec,這是一個Microsoft定義的關鍵字。
              (2) 創建一個模板定義文件(Module-Definition File,即.DEF)。
              第一種方法稍稍比第二種方法簡單,在這里我們使用的是第一種方法。
                __declspec(dllexport)函數的作用是導出函數符號到在你的Dll中的一個存儲類里去。
            當下面一行被定義時我定義DECLDIR宏來運行這個函數。
                #define DLL_EXPORT
            在此情況下你將導出函數Add(int a,int b)和Function().
            4.創建一個源文件(名字為dll_test.cpp),內容如下:
             
            
             1 #include <iostream>
             2 #define DLL_EXPORT
             3 #include "dll_test.h"
             4 
             5 extern "C"
             6 {
             7         // 定義了(DLL中的)所有函數
             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 
            【第二步】使用創建好的DLL
            現在已經創建了DLL,那么如何在一個應用程序中使用它呢?
            當DLL被生成后,它創建了一個.dll文件和一個.lib,這兩個都是使用dll時需要用到的。
            在具體介紹之前先看一下dll的鏈接方式。
            (1)隱式連接
            這里有兩個方法來載入一個DLL,一個方法是只鏈接到.lib文件,并將.dll文件放到要使用這個DLL的項目路徑中。
            因此,創建一個新的空的Win32控制臺項目并添加一個源文件。將我們創建好的DLL放入與新項目相同的目錄下。同時我們還必須鏈接到dll_test.lib文件。
            可以在項目屬性中設置,也可以在源程序中用下面的語句來鏈接:
            #pragma comment(lib, "dll_test.lib")
            最后,我們還要在新的win32控制臺項目中包含前面的dll_test.h頭文件。可以把這個頭文件放到新建win32控制臺項目的目錄中然后在程序中加入語句:
            #include "dll_test.h"
            新項目代碼如下:
            #include<iostream>
            #include "DLLTutorial.h"
            int main()
            {
              Function();
              std::cout<< Add(32, 56)<< endl;
              return 0;
            }
            (2)顯示鏈接
            稍微復雜一點的加載DLL的方法需要用到函數指針和一些Windows函數。但是,通過這種載入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);
            }
            /*******************************************************************/
            首先可以看到,這里包括進了windows.h頭文件,同時去掉了對dll_test.h頭文件的包含。原因很簡單:因為windows.h包含了一些Windows函數,
            它也包含了一些將會用到的Windows特定變量??梢匀サ鬌LL的頭文件,因為當使用這個方法載入DLL時并不需要其頭文件。
            下面你會看到:以下面形式的一小塊古靈精怪的代碼:
                typedef int (*AddFunc)(int,int);
            typedef void (*FunctionFunc)();
                這是函數指針。因為這是一個關于DLL的自學指南,深入探究函數指針超出了本指南的范圍;因此,現在我們只把它們當作DLL包含的函數的別名。
                我喜歡在尾部用“Func”命名之。(int,int)部分是這個函數的參數部分,比如,Add函數要獲得兩個整數;因此,你需要它們
            (譯注:指(int,int)部分)作為函數指針的參數。Function函數沒有參數,因此你讓它為空。main()部分中的前面兩行是聲明函數指針以使得你可
            以認為它們等同于DLL內部的函數。我只是喜歡預先定義它們。
                  一個HINSTANCE是一個Windows數據類型:是一個實例的句柄;在此情況下,這個實例將是這個DLL。你可以通過使用函數LoadLibrary()獲得DLL的
            實例,它獲得一個名稱作為參數。
                 在調用LoadLibrary函數后,你必需查看一下函數返回是否成功。你可以通過檢查HINSTANCE是否等于NULL(在Windows.h中定義為0或Windows.h包
            含的一個頭文件)來查看其是否成功。如果其等于NULL,該句柄將是無效的,并且你必需釋放這個庫。換句話說,你必需釋放DLL獲得的內存。
                  如果函數返回成功,你的HINSTANCE就包含了指向DLL的句柄。一旦你獲得了指向DLL的句柄,你現在可以從DLL中重新獲得函數。
                 為了這樣作,你必須使用函數GetProcAddress(),它將DLL的句柄(你可以使用HINSTANCE)和函數的名稱作為參數。你可以讓函數指針獲得由
            GetProcAddress()返回的值,同時你必需將GetProcAddress()轉換為那個函數定義的函數指針。舉個例子,對于Add()函數,你必需將GetProcAddress()
            轉換為AddFunc;這就是它知道參數及返回值的原因。現在,最好先確定函數指針是否等于NULL以及它們擁有DLL的函數。
                 這只是一個簡單的if語句;如果其中一個等于NULL,你必需如前所述釋放庫。一旦函數指針擁有DLL的函數,你現在就可以使用它們了,但是這里有一個
            需要注意的地方:你不能使用函數的實際名稱;你必需使用函數指針來調用它們。在那以后,所有你需要做的是釋放庫如此而已。
                 現在你知道了DLL的一些基本知識。你知道如何創建它們,你也知道如何用兩種不同的方法鏈接它們。這里仍然有更多的東西需要我們學習,但我把它們留給你們自己探索了和更棒的作者來寫了。
            
            996久久国产精品线观看| 麻豆久久| 久久99热只有频精品8| 久久精品国产99久久无毒不卡 | 香蕉久久一区二区不卡无毒影院 | 丰满少妇人妻久久久久久| av无码久久久久久不卡网站| 精品一区二区久久| 伊人久久成人成综合网222| 久久男人Av资源网站无码软件| 久久国产精品-国产精品| 久久人妻少妇嫩草AV蜜桃| 久久久久久狠狠丁香| 丁香色欲久久久久久综合网| 国产69精品久久久久99| 久久天天躁狠狠躁夜夜网站| 久久久久国产精品麻豆AR影院| 国产精品99久久久精品无码| 中文字幕一区二区三区久久网站| 中文字幕久久精品| 久久五月精品中文字幕| 97精品久久天干天天天按摩| 久久久久亚洲AV片无码下载蜜桃| 99精品伊人久久久大香线蕉| 精品永久久福利一区二区| 性做久久久久久久久| 久久精品国产99久久久香蕉| 久久国产一区二区| 久久国产精品久久国产精品| 天天爽天天狠久久久综合麻豆| 久久国产AVJUST麻豆| 亚洲v国产v天堂a无码久久| 久久精品国产精品青草| 久久精品国产亚洲77777| 亚洲精品无码久久久久sm| 国产精品久久久香蕉| 国产99久久久国产精品小说| 亚洲人AV永久一区二区三区久久| 亚洲欧美另类日本久久国产真实乱对白| 日韩精品久久久久久| 狠狠人妻久久久久久综合|