VC 動態鏈結庫程式設計之非MFC DLL

2021-05-21 10:54:17 字數 2463 閱讀 4187

4.1乙個簡單的dll

第2節給出了以靜態鏈結庫方式提供add函式介面的方法,接下來我們來看看怎樣用動態鏈結庫實現乙個同樣功能的add函式。

圖6 建立乙個非mfc dll

在建立的工程中新增lib.h及lib.cpp檔案,源**如下:

/* 檔名:lib.h */

#ifndef lib_h

#define lib_h

extern "c" int __declspec(dllexport)add(int x, int y);

#endif

/* 檔名:lib.cpp */

#include "lib.h"

int add(int x, int y)

#include

#include

typedef int(*lpaddfun)(int, int); //巨集定義函式指標型別

int main(int argc, char *argv)

freelibrary(hdll);

}return 0;}

分析上述**,dlltest工程中的lib.cpp檔案與第2節靜態鏈結庫版本完全相同,不同在於lib.h對函式add的宣告前面新增了__declspec(dllexport)語句。這個語句的含義是宣告函式add為dll的匯出函式。dll內的函式分為兩種:

(1)dll匯出函式,可**用程式呼叫;

(2) dll內部函式,只能在dll程式使用,應用程式無法呼叫它們。

而應用程式對本dll的呼叫和對第2節靜態鏈結庫的呼叫卻有較大差異,下面我們來逐一分析。

首先,語句typedef int ( * lpaddfun)(int,int)定義了乙個與add函式接受引數型別和返回值均相同的函式指標型別。隨後,在main函式中定義了lpaddfun的例項addfun;

其次,在函式main中定義了乙個dll hinstance控制代碼例項hdll,通過win32 api函式loadlibrary動態載入了dll模組並將dll模組控制代碼賦給了hdll;

再次,在函式main中通過win32 api函式getprocaddress得到了所載入dll模組中函式add的位址並賦給了addfun。經由函式指標addfun進行了對dll中add函式的呼叫;

最後,應用工程使用完dll後,在函式main中通過win32 api函式freelibrary釋放了已經載入的dll模組。

通過這個簡單的例子,我們獲知dll定義和呼叫的一般概念:

(1)dll中需以某種特定的方式宣告匯出函式(或變數、類);

(2)應用工程需以某種特定的方式呼叫dll的匯出函式(或變數、類)。

下面我們來對「特定的方式進行」闡述。

4.2 宣告匯出函式

dll中匯出函式的宣告有兩種方式:一種為4.1節例子中給出的在函式宣告中加上__declspec(dllexport),這裡不再舉例說明;另外一種方式是採用模組定義(.def) 檔案宣告,.def檔案為鏈結器提供了有關被鏈結程式的匯出、屬性及其他方面的資訊。

下面的**演示了怎樣同.def檔案將函式add宣告為dll匯出函式(需在dlltest工程中新增lib.def檔案):

; lib.def : 匯出dll函式

library dlltest

exports

add @ 1

),將編譯dlltest工程所生成的.lib和.dll檔案拷入dllcall工程所在的路徑,dllcall執行下列**:

#pragma comment(lib,"dlltest.lib")

//.lib檔案中僅僅是關於其對應dll檔案中函式的重定位資訊

extern "c" __declspec(dllimport) add(int x,int y);

int main(int argc, char* argv)

由上述**可以看出,靜態呼叫方式的順利進行需要完成兩個動作:

(1)告訴編譯器與dll相對應的.lib檔案所在的路徑及檔名,#pragma comment(lib,"dlltest.lib")就是起這個作用。

程式設計師在建立乙個dll檔案時,聯結器會自動為其生成乙個對應的.lib檔案,該檔案包含了dll 匯出函式的符號名及序號(並不含有實際的**)。在應用程式裡,.lib檔案將作為dll的替代檔案參與編譯。

(2)宣告匯入函式,extern "c" __declspec(dllimport) add(int x,int y)語句中的__declspec(dllimport)發揮這個作用。

靜態呼叫方式不再需要使用系統api來載入、解除安裝dll以及獲取dll中匯出函式的位址。這是因為,當程式設計師通過靜態鏈結方式編譯生成應用程式時,應用程式中呼叫的與.lib檔案中匯出符號相匹配的函式符號將進入到生成的exe 檔案中,.lib檔案中所包含的與之對應的dll檔案的檔名也被編譯器儲存在 exe檔案內部。當應用程式執行過程中需要載入dll檔案時,windows將根據這些資訊發現並載入dll,然後通過符號名實現對dll 函式的動態鏈結。這樣,exe將能直接通過函式名呼叫dll的輸出函式,就象呼叫程式內部的其他函式一樣。

VC 動態鏈結庫程式設計之非MFC DLL

4.1乙個簡單的dll 第2節給出了以靜態鏈結庫方式提供add函式介面的方法,接下來我們來看看怎樣用動態鏈結庫實現乙個同樣功能的add函式。圖6 建立乙個非mfc dll 在建立的工程中新增lib.h及lib.cpp檔案,源 如下 檔名 lib.h ifndef lib h define lib h...

VC 動態鏈結庫程式設計之非MFC DLL

4.1乙個簡單的dll 第2節給出了以靜態鏈結庫方式提供add函式介面的方法,接下來我們來看看怎樣用動態鏈結庫實現乙個同樣功能的add函式。圖6 建立乙個非mfc dll 在建立的工程中新增lib.h及lib.cpp檔案,源 如下 檔名 lib.h ifndef lib h define lib h...

VC 動態鏈結庫 DLL 程式設計

vc 動態鏈結庫 dll 程式設計 一 理解庫 vc 動態鏈結庫 dll 程式設計 二 非mfc dll vc 動態鏈結庫 dll 程式設計 三 mfc規則dll vc 動態鏈結庫 dll 程式設計 四 mfc擴充套件 dll vc 動態鏈結庫 dll 程式設計 五 dll典型例項 動態鏈結庫 dl...