如果使用VC编写DLL时,需要MFC功能; 一般在源文件里就不能手动写DLLMAIN函数了
它给MFC集成了,\src\mfc\dllmodule.cpp
打开它,里面有有一个DLLMAIN函数,根据源码意思就可以看出来,
这里截取的一点点代码
if (dwReason == DLL_PROCESS_ATTACH)
{
BOOL bResult = FALSE;
#ifdef _AFXDLL
// wire up resources from core DLL
AfxCoreInitModule();
#endif
_AFX_THREAD_STATE* pState = AfxGetThreadState();
AFX_MODULE_STATE* pPrevModState = pState->m_pPrevModuleState;
// Initialize DLL's instance(/module) not the app's
if (!AfxWinInit(hInstance, NULL, _T(""), 0))
{
AfxWinTerm();
goto Cleanup; // Init Failed
}
// initialize the single instance DLL
CWinApp* pApp; pApp = AfxGetApp();////关键在这里了
if (pApp != NULL && !pApp->InitInstance())///这里会调用 初始化函数
{
pApp->ExitInstance();///这也是退出时函数
AfxWinTerm();
goto Cleanup; // Init Failed
}
pState->m_pPrevModuleState = pPrevModState;
#ifdef _AFXDLL
// wire up this DLL into the resource chain
VERIFY(AfxInitExtensionModule(controlDLL, hInstance));
TRY
{
CDynLinkLibrary* pDLL;
pDLL = new CDynLinkLibrary(controlDLL);
}
CATCH(CMemoryException, e)
{
DELETE_EXCEPTION(e);
pApp->ExitInstance();
AfxWinTerm();
goto Cleanup; // Init Failed
}
END_CATCH
DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
这是莪们关心的,从上面代码中可以看到,这里面MFC调用一个全局的CWinApp类的 初始化函数
也就是说,现在写一个类,让它继承CWinApp
然后重载它的InitInstace 和ExitInstace就可以了
在InitInstace时里面写入所需要的代码就可以了
然后在声明一个全局的变量,一定要是个全局变量
当然这个类可以不用做任何事情,就提供初始化和退出时处理的函数
如果在DLL 动态库中导出全局变量
extern int __decspec
如果EXE中要使用DLL中的资源,因为DLL和EXE的资源ID很有可能会冲突,在函数第一行加入如下代码可解决此问题
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AFX_MANAGE_STATE是一个宏,其原型为:
AFX_MANAGE_STATE( AFX_MODULE_STATE* pModuleState )
该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指向栈上对象的作用域),先前的模块状态将由AFX_MODULE_STATE的析构函数恢复。
方法二 在DLL接口函数中使用:
AfxGetResourceHandle();
AfxSetResourceHandle(HINSTANCE xxx);
AfxGetResourceHandle用于获取当前资源模块句柄,而AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄。
我们将DLL中的接口函数ShowDlg改为:
void ShowDlg(void)
{
//方法2的状态变更
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框
dlg.DoModal();
//方法2的状态还原
AfxSetResourceHandle(save_hInstance);