VC 动态链接库(DLL)编程深入浅出4

2019-03-15 12:25

这是《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:

extern \

DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {

// Remove this if you use lpReserved UNREFERENCED_PARAMETER(lpReserved);

if (dwReason == DLL_PROCESS_ATTACH) {

TRACE0(\

// Extension DLL one-time initialization

if (!AfxInitExtensionModule(MfcexpenddllDLL, hInstance)) return 0;

// Insert this DLL into the resource chain

// NOTE: If this Extension DLL is being implicitly linked to by // an MFC Regular DLL (such as an ActiveX Control) // instead of an MFC application, then you will want to // remove this line from DllMain and put it in a separate // function exported from this Extension DLL. The Regular DLL // that uses this Extension DLL should then explicitly call that // function to initialize this Extension DLL. Otherwise, // the CDynLinkLibrary object will not be attached to the // Regular DLL's resource chain, and serious problems will // result.

new CDynLinkLibrary(MfcexpenddllDLL); }

else if (dwReason == DLL_PROCESS_DETACH) {

TRACE0(\ // Terminate the library before destructors are called AfxTermExtensionModule(MfcexpenddllDLL); }

return 1; // ok }

上述代码完成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

#define SXBUTTON_CENTER -1

class AFX_EXT_CLASS CSXButton : public CButton {

// Construction public: CSXButton();

// Attributes private: // Positioning

BOOL m_bUseOffset; CPoint m_pointImage; CPoint m_pointText;

int m_nImageOffsetFromBorder; int m_nTextOffsetFromImage;

// Image

HICON m_hIcon; HBITMAP m_hBitmap;

HBITMAP m_hBitmapDisabled;

int m_nImageWidth, m_nImageHeight;

// Color Tab

char m_bColorTab; COLORREF m_crColorTab;

// State

BOOL m_bDefault; UINT m_nOldAction; UINT m_nOldState;

// Operations public: // Positioning

int SetImageOffset( int nPixels ); int SetTextOffset( int nPixels ); CPoint SetImagePos( CPoint p ); CPoint SetTextPos( CPoint p );

// Image

BOOL SetIcon( UINT nID, int nWidth, int nHeight ); BOOL SetBitmap( UINT nID, int nWidth, int nHeight );

BOOL SetMaskedBitmap( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask );

BOOL HasImage() { return (BOOL)( m_hIcon != 0 | m_hBitmap != 0 ); }

// Color Tab

void SetColorTab(COLORREF crTab);

// State

BOOL SetDefaultButton( BOOL bState = TRUE ); private:

BOOL SetBitmapCommon( UINT nID, int nWidth, int nHeight, COLORREF crTransparentMask, BOOL bUseMask );

void CheckPointForCentering( CPoint &p, int nWidth, int nHeight ); void Redraw();

// Overrides

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSXButton) public:

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); //}}AFX_VIRTUAL

// Implementation public:

virtual ~CSXButton();

// Generated message map functions protected:

//{{AFX_MSG(CSXButton)

afx_msg LRESULT OnGetText(WPARAM wParam, LPARAM lParam); //}}AFX_MSG

DECLARE_MESSAGE_MAP() }; #endif

把SXBUTTON.CPP文件直接添加到工程,编译工程,得到“mfcexpenddll.lib”和“mfcexpenddll.dll”两个文 件。我们用Visual Studio自带的Depends工具可以查看这个.dll,发现其导出了众多符号(见图15)。

图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


VC 动态链接库(DLL)编程深入浅出4.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:三年级数学下册除法计算题专题训练

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: