随笔 - 119  文章 - 290  trackbacks - 0

博客搬家了哦,请移步
叫我abc

常用链接

留言簿(12)

随笔分类

我的博客

搜索

  •  

积分与排名

  • 积分 - 301920
  • 排名 - 84

最新评论

阅读排行榜

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

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

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

不过在尝试的过程中,出了点问题,在调用导出函数的时候不是崩溃就是大量的DEBUG ASSERT,看起来卡在CFileDialog的构造函数上了。
请教同事,才知道大概缘由。
在MFC常规DLL自带的DllMain函数中,有这么一些细节,在下面的中文注释中标注
 1extern "C"
 2BOOL 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
 1BOOL 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程序,不过我不是很喜欢这样
posted on 2008-05-19 22:06 LOGOS 阅读(2804) 评论(1)  编辑 收藏 引用

FeedBack:
# re: 使用MFC常规DLL 2008-05-21 20:07 编程的夜猫
好啊,学习了。以后会注意的,感谢楼主  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理