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

2021-05-25 10:31:07 字數 3860 閱讀 5747

這是《vc++動態鏈結庫(dll)程式設計深入淺出》的第四部分,閱讀本文前,請先閱讀前三部分:(一)、(二)、(三)。

mfc擴充套件dll的內涵為mfc的擴充套件,使用者使用mfc擴充套件dll就像使用mfc本身的dll一樣。除了可以在mfc擴充套件dll的內部使用mfc以外,mfc擴充套件dll與應用程式的介面部分也可以是mfc。我們一般使用mfc擴充套件dll來包含一些mfc的增強功能,譬如擴充套件mfc的cstatic、cbutton等類使之具備更強大的能力。

使用visual c++嚮導生產mfc擴充套件dll時,mfc嚮導會自動增加dll的入口函式dllmain:

上述**完成mfc擴充套件dll的初始化和終止處理。

由於mfc擴充套件dll匯出函式和變數的方式與其它dll沒有什麼區別,我們不再細緻講解。下面直接給出乙個mfc擴充套件dll的建立及在應用程式中呼叫它的例子。

6.1 mfc擴充套件dll的建立

下面我們將在mfc擴充套件dll中匯出乙個按鈕類csxbutton(擴充套件自mfc的cbutton類),類csxbutton是乙個用以取代 cbutton的類,它使你能在同乙個按鈕上顯示點陣圖和文字,而mfc的按鈕僅可顯示二者之一。類csxbutton的源**在internet上廣泛流傳,有很好的「群眾基礎」,因此用這個類來講解mfc擴充套件dll有其特殊的功效。

mfc中包含一些巨集,這些巨集在dll和呼叫dll的應用程式中被以不同的方式展開,這使得在dll和應用程式中,使用統一的乙個巨集就可以表示出輸出和輸入的不同意思:

// for data

#ifndef afx_data_export

#define afx_data_export __declspec(dllexport)

#endif

#ifndef afx_data_import

#define afx_data_import __declspec(dllimport)

#endif

// for classes

#ifndef afx_class_export

#define afx_class_export __declspec(dllexport)

#endif

#ifndef afx_class_import

#define afx_class_import __declspec(dllimport)

#endif

// for global apis

#ifndef afx_api_export

#define afx_api_export __declspec(dllexport)

#endif

#ifndef afx_api_import

#define afx_api_import __declspec(dllimport)

#endif

#ifndef afx_ext_data

#ifdef _afxext

#define afx_ext_class    afx_class_export

#define afx_ext_api     afx_api_export

#define afx_ext_data    afx_data_export

#define afx_ext_datadef

#else

#define afx_ext_class    afx_class_import

#define afx_ext_api     afx_api_import

#define afx_ext_data    afx_data_import

#define afx_ext_datadef

#endif

#endif匯出乙個類,直接在類宣告標頭檔案中使用afx_ext_class即可,以下是匯出csxbutton類的例子:

#ifndef _sxbutton_h

#define _sxbutton_h

#definesxbutton_center-1

class afx_ext_class csxbutton : public cbutton

//color tab

voidsetcolortab(colorref crtab);

//state

boolsetdefaultbutton( bool bstate = true );

private:

boolsetbitmapcommon( uint nid, int nwidth, int nheight, colorref crtransparentmask, bool busemask );

voidcheckpointforcentering( cpoint &p, int nwidth, int nheight );

voidredraw();

// overrides

// classwizard generated virtual function overrides

//}afx_virtual

// implementation

public:

virtual ~csxbutton();

// generated message map functions

protected:

//}afx_msg

declare_message_map()

};#endif把sxbutton.cpp檔案直接新增到工程,編譯工程,得到「mfcexpenddll.lib」和「mfcexpenddll.dll」兩個檔案。我們用visual studio自帶的depends工具可以檢視這個.dll,發現其匯出了眾多符號(見圖15)。

這些都是類的建構函式、析構函式及其它成員函式和變數經編譯器處理過的符號,我們直接用__declspec(dllexport)語句宣告類就匯出了這些符號。

如果我們想用.lib檔案匯出這些符號,是非常困難的,我們需要在工程中生成.map檔案,查詢.map檔案的符號,然後將其一一匯出。如圖16,開啟dll工程的settings選項,再選擇link,勾選其中的產生map檔案(generate mapfile)就可以產生.map檔案了。

開啟mfcexpenddll工程生成的.map檔案,我們發現其中包含了圖15中所示的符號(symbol)

0001:00000380 ?hasimage@csxbutton@@qaehxz 10001380 f i sxbutton.obj

0001:000003d0 ??0csxbutton@@qae@xz    100013d0 f  sxbutton.obj

0001:00000500 ??_gcsxbutton@@uaepaxi@z  10001500 f i sxbutton.obj

0001:00000570 ??_ecsxbutton@@uaepaxi@z  10001570 f i sxbutton.obj

0001:00000630 ??1csxbutton@@uae@xz    10001630 f  sxbutton.obj

0001:00000700 ?_getbasemessagemap@csxbutton@@kgpbuafx_msgmap@@xz 10001700 f  sxbutton.obj

0001:00000730 ?getmessagemap@csxbutton@@mbepbuafx_msgmap@@xz 10001730 f  sxbutton.obj

0001:00000770  ?redraw@csxbutton@@aaexxz 10001770 f i sxbutton.obj

0001:000007d0  ?seticon@csxbutton@@qaehihh@z 100017d0 f  sxbutton.obj

……………………………………………………………………..//省略

所以,對於mfc擴充套件dll,我們不宜以.lib檔案匯出類。

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