VC 動態鏈結庫 DLL 程式設計深入淺出之二(3)

2021-05-23 01:37:24 字數 3662 閱讀 1172

/* 檔名:lib.h */

#ifndef lib_h

#define lib_h

extern int dllglobalvar;

#endif

/* 檔名:lib.cpp */

#include "lib.h"

#include

int dllglobalvar;

bool apientry dllmain(handle hmodule, dword ul_reason_for_call, lpvoid lpreserved)

return true;

};檔名:lib.def

;在dll中匯出變數

library "dlltest"

exports

dllglobalvar constant

;或dllglobalvar data

getglobalvar

從lib.h和lib.cpp中可以看出,全域性變數在dll中的定義和使用方法與一般的程式設計是一樣的。若要匯出某全域性變數,我們需要在.def檔案的exports後新增:

變數名 constant   //過時的方法

或變數名 data     //vc++提示的新方法

在主函式中引用dll中定義的全域性變數:

#include

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

extern int dllglobalvar;

int main(int argc, char *argv)

特別要注意的是用extern int dllglobalvar宣告所匯入的並不是dll中全域性變數本身,而是其位址,應用程式必須通過強制指標轉換來使用dll中的全域性變數。這一點,從*(int*)dllglobalvar可以看出。因此在採用這種方式引用dll全域性變數時,千萬不要進行這樣的賦值操作:

dllglobalvar = 1;

其結果是dllglobalvar指標的內容發生變化,程式中以後再也引用不到dll中的全域性變數了。

在應用工程中引用dll中全域性變數的乙個更好方法是:

#include

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

extern int _declspec(dllimport) dllglobalvar; //用_declspec(dllimport)匯入

int main(int argc, char *argv)

4.7 dll匯出類

dll中定義的類可以在應用工程中使用。

附件)。

//檔名:point.h,point類的宣告

#ifndef point_h

#define point_h

#ifdef dll_file

class _declspec(dllexport) point //匯出類point

#else

class _declspec(dllimport) point //匯入類point

#endif

;#endif

//檔名:point.cpp,point類的實現

#ifndef dll_file

#define dll_file

#endif

#include "point.h"

//類point的預設建構函式

point::point()

//類point的建構函式

point::point(float x_coordinate, float y_coordinate)

//檔名:circle.h,circle類的宣告

#ifndef circle_h

#define circle_h

#include "point.h"

#ifdef dll_file

class _declspec(dllexport)circle //匯出類circle

#else

class _declspec(dllimport)circle //匯入類circle

#endif

;#endif

//檔名:circle.cpp,circle類的實現

#ifndef dll_file

#define dll_file

#endif

#include "circle.h"

#define pi 3.1415926

//circle類的建構函式

circle::circle()

//得到圓的面積

float circle::getarea()

//得到圓的周長

float circle::getgirth()

//設定圓心座標

void circle::setcentre(const point ¢repoint)

//設定圓的半徑

void circle::setradius(float r)

類的引用:

#include "../circle.h"  //包含類宣告標頭檔案

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

int main(int argc, char *argv)

從上述源**可以看出,由於在dll的類實現**中定義了巨集dll_file,故在dll的實現中所包含的類宣告實際上為:

class _declspec(dllexport) point //匯出類point 和

class _declspec(dllexport) circle //匯出類circle

而在應用工程中沒有定義dll_file,故其包含point.h和circle.h後引入的類宣告為:

class _declspec(dllimport) point //匯入類point 和

class _declspec(dllimport) circle //匯入類circle

不錯,正是通過dll中的

class _declspec(dllexport) class_name //匯出類circle 

與應用程式中的

class _declspec(dllimport) class_name //匯入類

匹對來完成類的匯出和匯入的!

我們往往通過在類的宣告標頭檔案中用乙個巨集來決定使其編譯為class _declspec(dllexport) class_name還是class _declspec(dllimport) class_name版本,這樣就不再需要兩個標頭檔案。本程式中使用的是:

#ifdef dll_file

class _declspec(dllexport) class_name //匯出類

#else

class _declspec(dllimport) class_name //匯入類

#endif

實際上,在mfc dll的講解中,您將看到比這更簡便的方法,而此處僅僅是為了說明_declspec(dllexport)與_declspec(dllimport)匹對的問題。

由此可見,應用工程中幾乎可以看到dll中的一切,包括函式、變數以及類,這就是dll所要提供的強大能力。只要dll釋放這些介面,應用程式使用它就將如同使用本工程中的程式一樣!

本章雖以vc++為平台講解非mfc dll,但是這些普遍的概念在其它語言及開發環境中也是相同的,其思維方式可以直接過渡。

VC 動態鏈結庫 DLL 程式設計深入淺出 一

1.概論 先來闡述一下dll dynamic linkable library 的概念,你可以簡單的把dll看成一種倉庫,它提供給你一些可以直接拿來用的變數 函式或類。在倉庫的發展史上經歷了 無庫 靜態鏈結庫 動態鏈結庫 的時代。2.靜態鏈結庫 對靜態鏈結庫的講解不是本文的重點,但是在具體講解dll...

VC 動態鏈結庫 DLL 程式設計深入淺出 二

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

VC 動態鏈結庫 DLL 程式設計深入淺出 一

1.概論 先來闡述一下dll dynamic linkable library 的概念,你可以簡單的把dll看成一種倉庫,它提供給你一些可以直接拿來用的變數 函式或類。在倉庫的發展史上經歷了 無庫 靜態鏈結庫 動態鏈結庫 的時代。圖1 建立乙個靜態鏈結庫 並新建lib.h和lib.cpp兩個檔案,l...