VC++环境下动态链接库的开发及应用
#ifdef _AFXEXT AFX_EXT_API AFX_API_EXPORT #else AFX_API_IMPORT #ifdef _AFXEXT AFX_EXT_DATA AFX_DATA_EXPORT #else AFX_DATA_IMPORT
4.2. MFC扩展DLL导出MFC派生类
在下述例子中,我们将新建一个名为“ExtDll”的MFC扩展DLL工程,在这个DLL中导出一个对话框类,这个对话框类派生自MFC类CDialog。
图 4-2-1 创建MFC扩展DLL
25
VC++环境下动态链接库的开发及应用
图 4-2-2 创建MFC扩展DLL
使用MFC向导生成MFC扩展DLL时,系统会自动添加如下代码:
static AFX_EXTENSION_MODULE ExtDllDLL = { NULL, NULL }; extern \
DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) {
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER( lpReserved );
//说明:lpReserved是一个被系统所保留的参数,对于隐式链接是一个非零值,对于显式链接值是零 if (dwReason == DLL_PROCESS_ATTACH) {
TRACE0( \ // Extension DLL one-time initialization
if ( !AfxInitExtensionModule( ExtDllDLL, hInstance )) return 0;
// Insert this DLL into the resource chain new CDynLinkLibrary( ExtDllDLL );
26
VC++环境下动态链接库的开发及应用
} else if (dwReason == DLL_PROCESS_DETACH) { TRACE0( \ // Terminate the library before destructors are called AfxTermExtensionModule( ExtDllDLL ); } return 1; // ok }
代码分析如下:
(1)上述代码完成MFC扩展DLL的初始化和终止处理;
(2)初始化期间所创建的 CDynLinkLibrary 对象使MFC扩展 DLL 可以将 DLL中的CRuntimeClass 对象或资源导出到应用程序;
(3)AfxInitExtensionModule函数捕获模块的CRuntimeClass 结构和在创建 CDynLinkLibrary 对象时使用的对象工厂(COleObjectFactory 对象);
(4)AfxTermExtensionModule函数使 MFC 得以在每个进程与扩展 DLL 分离时(进程退出或使用AfxFreeLibrary卸载DLL时)清除扩展 DLL;
(5)第一条语句static AFX_EXTENSION_MODULE ExtDllDLL = { NULL, NULL };定义了一个AFX_EXTENSION_MODULE类的静态全局对象,AFX_EXTENSION_MODULE的定义如下:
struct AFX_EXTENSION_MODULE { BOOL bInitialized; HMODULE hModule; HMODULE hResource; CRuntimeClass* pFirstSharedClass; COleObjectFactory* pFirstSharedFactory; };
在资源编辑器中添加一个如下图所示的对话框,并使用MFC类向导为其添加一个
27
VC++环境下动态链接库的开发及应用
对应的类CExtDialog,系统自动添加了ExtDialog.h和ExtDialog.cpp两个头文件。
图 4-2-3 添加对话框
图 4-2-3 添加对话框类
修改ExtDialog.h中CExtDialog类的声明为:
28