VC++动态链接库编程之MFC扩展 DLL 2

来源:互联网 发布:centos 6.5 u盘启动盘 编辑:程序博客网 时间:2024/05/08 15:41
导读:


 6.3 MFC扩展DLL的加载


  6.3.1 隐式加载


  我们在6.2工程所在的工作区中添加一个LoadExtDllDlg工程,用于演示MFC扩展DLL的加载。在LoadExtDllDlg工程中添加一个如图16所示的对话框,这个对话框上包括一个“调用DLL”按钮。








图16 MFC扩展DLL调用工程中的对话框


  在与图16对应对话框类实现文件的头部添加:


// LoadExtDllDlg.cpp : implementation file


//


#include "../ExtDialog.h"


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


而“调用DLL”按钮的单击事件的消息处理函数为:


void CLoadExtDllDlg::OnDllcallButton()


{


 CExtDialog extDialog;


 extDialog.DoModal();


}


  当我们单击“调用DLL”的时候,弹出了如图15的对话框。


  为提供给用户隐式加载(MFC扩展DLL一般使用隐式加载,具体原因见下节),MFC扩展DLL需要提供三个文件:


  (1)描述DLL中扩展类的头文件;


  (2)与动态链接库对应的.LIB文件;


  (3)动态链接库.DLL文件本身。


  有了这三个文件,应用程序的开发者才可充分利用MFC扩展DLL。


  6.3.2 显示加载


  显示加载MFC扩展DLL应使用MFC全局函数AfxLoadLibrary而不是WIN32 API中的LoadLibrary。AfxLoadLibrary 最终也调用了 LoadLibrary这个API,但是在调用之前进行了线程同步的处理。


  AfxLoadLibrary 的函数原型与 LoadLibrary完全相同,为:


HINSTANCE AFXAPI AfxLoadLibrary( LPCTSTR lpszModuleName );


  与之相对应的是,MFC 应用程序应使用AfxFreeLibrary 而非FreeLibrary 卸载MFC扩展DLL。AfxFreeLibrary的函数原型也与 FreeLibrary完全相同,为:


BOOL AFXAPI AfxFreeLibrary( HINSTANCE hInstLib );


  如果我们把上例中的“调用DLL”按钮单击事件的消息处理函数改为:


void CLoadExtDllDlg::OnDllcallButton()


{


 HINSTANCE hDll = AfxLoadLibrary( "ExtDll.dll" );


 if(NULL == hDll)


 {


  AfxMessageBox( "MFC扩展DLL动态加载失败" );


  return;


 }


 CExtDialog extDialog;


 extDialog.DoModal();


 AfxFreeLibrary(hDll);


}


  则工程会出现link错误:


LoadExtDllDlg.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall CExtDialog::~CExtDialog(void)" (__imp_??1CExtDialogUAE@XZ)


LoadExtDllDlg.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall CExtDialog::CExtDialog(class CWnd *)" (__imp_??0CExtDialogQAE@PAVCWnd@Z)


  提示CExtDialog的构造函数和析构函数均无法找到!是的,对于派生MFC类的MFC扩展DLL,当我们要在应用程序中使用DLL中定义的派生类时,我们不宜使用动态加载DLL的方法。


  6.4 MFC扩展DLL加载MFC扩展DLL


  我们可以在MFC扩展DLL中再次使用MFC扩展DLL,但是,由于在两个DLL中对于AFX_EXT_CLASS、AFX_EXT_API、AFX_EXT_DATA宏的定义都是输出,这会导致调用的时候出现问题。


  我们将会在调用MFC扩展DLL的DLL中看到link错误:


error LNK2001: unresolved external symbol ….......


  因此,在调用MFC扩展DLL的MFC扩展DLL中,在包含被调用DLL的头文件之前,需要临时重新定义AFX_EXT_CLASS的值。下面的例子显示了如何实现:


//临时改变宏的含义“输出”为“输入”


#undef AFX_EXT_CLASS


#undef AFX_EXT_API


#undef AFX_EXT_DATA


#define AFX_EXT_CLASS AFX_CLASS_IMPORT


#define AFX_EXT_API AFX_API_IMPORT


#define AFX_EXT_DATA AFX_DATA_IMPORT


//包含被调用MFC扩展DLL的头文件


#include "CalledDLL.h"


//恢复宏的含义为输出


#undef AFX_EXT_CLASS


#undef AFX_EXT_API


#undef AFX_EXT_DATA


#define AFX_EXT_CLASS AFX_CLASS_EXPORT


#define AFX_EXT_API AFX_API_EXPORT


#define AFX_EXT_DATA AFX_DATA_EXPORT





本文转自


http://tech.163.com/05/1010/10/1VMP5SN900091589_2.html