使用MFC常规DLL

使用MFC常规DLL
最近知道可以使用MFC常规DLL导出一些功能,交给其他程序使用,即使那个程序不是MFC程序。

尝试的环境大概是这样的,MFC常规DLL,以及普通的控制台程序。
MFC常规DLL的一个导出函数
1 __declspec( dllexport )  void  create_frm2()
2 {
3    CFileDialog dlg( TRUE );
4    dlg.DoModal();
5}

调用导出函数的应用程序
1 int  _tmain( int  argc, _TCHAR *  argv[])
2 {
3    create_frm2();
4
5    return 0;
6}

不过在尝试的过程中,出了点问题,在调用导出函数的时候不是崩溃就是大量的DEBUG ASSERT,看起来卡在CFileDialog的构造函数上了。
请教同事,才知道大概缘由。
在MFC常规DLL自带的DllMain函数中,有这么一些细节,在下面的中文注释中标注
 1 extern   " C "
 2 BOOL WINAPI InternalDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID  /**/ /*lpReserved*/ )
 3 {
 4    if (dwReason == DLL_PROCESS_ATTACH)
 5    {
 6        
 7
 8        _AFX_THREAD_STATE* pState = AfxGetThreadState();
 9        //下面这句,保存了前一个模块的module state。
10        //但是如果前一个模块是非MFC程序,那么pPrevModState=0
11        AFX_MODULE_STATE* pPrevModState = pState->m_pPrevModuleState;
12
13        
14
15        // initialize the single instance DLL
16        CWinApp* pApp; pApp = AfxGetApp();
17        if (pApp != NULL && !pApp->InitInstance())
18        {
19            pApp->ExitInstance();
20            AfxWinTerm();
21            goto Cleanup;       // Init Failed
22        }

23
24        
25
26        bResult = TRUE;
27
28Cleanup:
29        pState->m_pPrevModuleState = pPrevModState;
30#ifdef _AFXDLL
31        // restore previously-saved module state
32        //这里,在退出DllMain前,将module state的指针设置为0
33        //以后AfxGetModuleState的值就是0了
34        //这样的情况下,MFC的很多方法和类根本无法使用
35        VERIFY(AfxSetModuleState(AfxGetThreadState()->m_pPrevModuleState) ==
36            &afxModuleState);
37        DEBUG_ONLY(AfxGetThreadState()->m_pPrevModuleState = NULL);
38#endif
39        return bResult;
40    }

41    
42    
43
44    return TRUE;
45}

由于我的调用程序不是MFC程序,所以MFC常规DLL中保存的module state值为0,当构造CFileDialog时,相关的地方就失败了。
知道原因,就知道解决方法了。
1.注意到DllMain恢复前一个module state的代码,是写在 #ifdef _AFXDLL里面的。也就是说,取消_AFXDLL的宏定义,module state的值就应该是有效的。
我将MFC常规DLL的编译选项Use Of MFC 改为 Use MFC In a Static Library后重新编译,执行正常。

2.第二个方法就是想办法设置一个module state,比如可以用MFC常规DLL中的那个module state
 1 BOOL Capp3App::InitInstance()
 2 {
 3    CWinApp::InitInstance();
 4
 5    //在MFC DLL中保存module state
 6    g_ms = AfxGetModuleState();
 7
 8    return TRUE;
 9}

10
11
12 __declspec( dllexport )  void  create_frm2()
13 {
14    //刚进来,这时候module state = 0
15    //将它设置为一个有效值
16    AfxSetModuleState( g_ms );
17    
18    CFileDialog dlg( TRUE );
19    dlg.DoModal();
20}

3.第三个方法就是,把调用程序换成MFC程序,不过我不是很喜欢这样

你可能感兴趣的:(使用MFC常规DLL)