MFC Extern DLL 资源切换问题 求大神解惑

marslycan 2018-11-15 05:29:50
以前上学时,开发项目往往都是独立的,很少涉及到动态库操作,导致此块认知薄弱,现在在公司开发相关软件的新版本,独立写了一个模块(一个对话框),用拓展动态库的形式加载了进去:
遇到一个问题,就是我想在我的对话框中加载一些资源会发现加载错误,资源句柄为空,代码如下:

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分了,论坛可以买积分么...很不好意思总是有问题才想起来积分..导致积分只出不进...
...全文
88 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
蒋晟 2018-11-17
  • 打赏
  • 举报
回复
扩展DLL里不应该用AfxGetStaticModuleState (KB Q161589: DOC: AfxGetStaticModuleState() Causes Errors in an Extension DLL) 加载资源的时候应该用AfxFindResourceHandle而不是AfxGetResourceHandle。AfxFindResourceHandle会首先去找AfxGetResourceHandle(这个默认是指向exe,像你那样改掉在调用别人的代码之前又不改回去会出问题),AfxGetResourceHandle下面找不到的话会去搜索当前的CDynLinkLibrary列表(也就是你的扩展DLL啦)。
marslycan 2018-11-16
  • 打赏
  • 举报
回复
引用 1 楼 chengbar 的回复:
应该使用MFC常规DLL

一开始我是写成常规的DLL的,但是遇到了阻力让我崩溃,各式各样的崩溃(比如因为里面有很多Custom控件,还要注册等等),也是我那时候刚接触DLL,后来Google了一个帖子,看到有人回复:Why are you doning this in a regular DLL?Wonldn't an externsion DLL more suitable? And you can avoid all this hassle.
发帖的人遇到的种种问题大概是与我一致的,搞得我头皮发麻,再加上大工程里其他模块也是拓展DLL,于是我就将我的模块重新写为了拓展的DLL,也确实解决了我当时遇到的所有问题。
而且常规DLL 也需要切换资源的吧~
sevancheng 2018-11-15
  • 打赏
  • 举报
回复
应该使用MFC常规DLL

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧