正在阅读:VC++动态链接库(DLL)编程深入浅出(四)VC++动态链接库(DLL)编程深入浅出(四)

2005-11-09 11:43 出处:PConline 作者:宋宝华 责任编辑:xietaoming

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
……………………………………………………………………..//省略
 

图16 产生.map文件 (+放大该图片)

  所以,对于MFC扩展DLL,我们不宜以.lib文件导出类。

键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品