以前上学时,开发项目往往都是独立的,很少涉及到动态库操作,导致此块认知薄弱,现在在公司开发相关软件的新版本,独立写了一个模块(一个对话框),用拓展动态库的形式加载了进去:
遇到一个问题,就是我想在我的对话框中加载一些资源会发现加载错误,资源句柄为空,代码如下:
m_hIcon1 = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
...
//或者
m_pThumbnailView->AddImage(AfxGetResourceHandle() IDB_BITMAP_DATASHEET);
查阅资料大概发现问题都集中在资源上,整理如下:
// MSDN
构建动态链接到MFC的常规DLL时,需要使用宏AFX_MANAGE_STATE正确切换MFC模块状态。 这是通过将以下代码行添加到从DLL导出的函数的开头来完成的:
AFX_MANAGE_STATE(AfxGetStaticModuleState())
但是我用的是拓展动态库,会报错XXX。然后继续查阅资料,有文提到使用
AFX_MANAGE_STATE宏不应在静态链接到MFC或扩展DLL的常规DLL中使用。
但是在MFC扩展dll里导出函数时应该也进行资源的切换。
有人说解决该错误的方式如下:
将上述宏替换为AFX_MANAGE_STATE(AfxGetStaticModuleState()),但好像这样设置的还是主进程的资源句柄。反正用了这个宏,我获取的还是不正确的。
链接:https://blog.csdn.net/matrix_designer/article/details/6336003
继续查阅资料..找到一个看似靠谱的办法,也确实有效果,暂时达到了我的目的:大概思路是在dllMain定义了一个资源句柄,并存储下来,然后在我的入口函数中通过Set的方式切换:
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(HistoryTrackDLLInstance);
CDialogEx::DoModal();
AfxSetResourceHandle(save_hInstance);
OK,目前为止,我的资源都Load正确,但是出现了新的问题,导致我现在的困惑,我困惑我这种做法究竟是否是标准的方式,因为在我的模块链接到主模块后,发现需要调用主模块的东西,比如InitDlg时,我要Load主工程一些信息,当Load出错时,它内部有一个错误机制将错误发送到主界面,导致主角面(MainFram)LoadString 时崩溃。
那么我应该怎么做? 我尝试Load函数中,时将资源切换回去,但他内部貌似是PostMessge还是什么机制,等消息发过去了,我的函数已经执行完,资源切换回去了。于是还是会崩溃。
描述有点乱,我想请大神指点一下,正确的操作各个DLL资源之间切换的方式,我应该如何避免上述问题(不是逃避问题)。
目前我的解决方式是,不再Domodal时切换了,而是在我的模块中Load资源时,直接给模块的全局句柄。感觉这么做不太好。
PS : 就剩72分了,论坛可以买积分么...很不好意思总是有问题才想起来积分..导致积分只出不进...