1. 程式人生 > >用VC++封裝自己的DLL動態連結庫

用VC++封裝自己的DLL動態連結庫

我的動態連結庫的製作,總結了一下,從小的簡單的dll逐漸逐層放大,記錄下來,以後方便查詢。

1.Win32 DLL的建立和使用

 首先利用vc++新建一個Win32Dynamic-Link Library 類的工程,工程取名為:Dll1,並在AppWizard的第一步選擇“An empty Dll project”選項,即建立一個空的動態連結庫工程。然後,為該工程新增一個c++原始檔Dll1.cpp,向其中新增函式,分別為:加法運算和減法運算函式,程式碼為:

int add(int a,int b)

{return a+b;}

int subtract(int a,int b)

{return a-b;}

點選bulid(CTRL+F7或者選中cpp檔案右鍵編譯)命令可生成動態連結庫,名字為Dll1.dll檔案。

生成DLL後,就可以匯出函式,但是需要在每一個將要被匯出的函式前面新增識別符號_declspec(dllexport),所以修改上述程式碼如下:

_declspec(dllexport) int add(int a,int b)

{return a+b;}

_declspec(dllexport) int subtract(int a,int b)

{return a-b;}

然後點選bulid命令,下面的視窗會輸出如下資訊:

——————Configuration:Dll1-Win32 Debug-------------——

Compiling...

Dll1.cpp

Linking ...

 Creating library Debug/Dll1.lib and object Debug/dll1.exp

Dll1.dll -0 error(s),0 wrning(s)

可以看到,生成兩個新檔案,其中Dll1.lib 檔案就是前面提到的引入庫檔案,該檔案儲存的是Dll1.dll中匯出的函式和變數的符號名:Dll1.exp檔案是一個輸出庫檔案,在這裡,該檔案並不重要。

因為C++支援函式過載,對於從在的多個函式來說,其函式名都是一樣的,為了加以區分,在編譯連線時,c++會按照自己的規則篡改函式的名稱,稱為“名字改編”,

2。隱式連結方式載入DLL

編寫一個測試程式測試這個動態庫,新建一個.cpp檔案取名為dlltest.cpp。

(1)利用extern宣告外部函式

為了讓編譯器知道這兩個函式,需要對函式做一個宣告,即在函式名前面加上extern 表示函式是在外部定義的。如下:

extern int add(int a,int b);

extern int subtract(int a,int b);

int main()

{

   printf("%d",add(5,3));

   printf("%d",subtract(6,4));

}

點選bulid命令,會出現三個錯誤:

linking...

error executing link.exe

可看出,編譯成功,因為add和subtract函式做了宣告,但在程式連線時出錯,因為聯結器沒有找到該資訊,

為了解決這個問題,需要利用動態連結庫的引入庫檔案,將Dll1..lib 和dll檔案複製到dlltest.cpp目錄下,然後再dlltest.cpp程式中,選擇【工程-設定-連線選項卡】在"附加依賴項"新增dll1.lib再次執行,就會成功。

(2)利用_declspc(dllimport)宣告外部函式

如:

_declspec(dllimport) int add(int a,int b);

 _declspec(dllimport) int subtract(int a,int b);

與使用extern關鍵字這種方式相比,使用_declspec(dllimport)識別符號宣告外部函式時,他將告訴編譯器該函式是從動態連結庫中引入的,編譯器可以生成執行效率更高的程式碼,因此,如果呼叫的函式來自於動態連結庫,因該採用這種方式宣告外部函式。

3。完善W32Dll例子

要想將生成的Dll提供給使用者,通常在編寫動態連結庫時,都會提供一個頭檔案,在此標頭檔案中提供Dll匯出函式原型的宣告,以及函式的有關注釋文件。

為Dll1工程新增一個頭檔案:Dll1.h 新增程式碼如下:

_declspec (dllimport) int add(int a,int b);

_declspec(dllimport) int subtract(int a,int b);

然後在測試檔案中新增#include"路徑/Dll1.h"