程序执行过程中的意外的模块跳转

风之子赛拉飞尔 2015-07-29 02:30:44
这个是我是当前实际遇到的问题,可能比较少见,但是一旦遇到不太容易定位原因。
所以在这里把解决过程记录下来。

主工程(Exe)是MFC的MDI工程,UI_Widget和UI_Base是选择使用MFC的Win32 DLL(改了个扩展名)。
这两个DLL中分别导出C++类,导出类包含MFC类类型的成员。在需要加的地方,已经都加上了:

AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxSetResourceHandle(hInstance); // 这个solution中使用了公共资源模块,hInstance即为其句柄


问题现象是运行时报从资源句柄中无法找到指定ID的对话框模版。
一开始百思不得其解,调查了很长时间后,才终于找到原因。



Exe调用UI_Widget的一个导出类C1的方法CreatePanel,CreatePanel是C1的基类C0的方法,
C1并未重载,所以直接进入了基类C0(位于模块UI_Base)。之后进入C0的基类CSubPanel,
再进入MFC基类CDialog,就在这里出现了一次意外的模块跳转,问题就出在这里。上面两句代码
调用位置是在UI_Base中,这次意外跳转后,回到模块UI_Widget,才进入MFC基类方法访问资源,
当然资源句柄是无效的。

出现意外跳转的原因推测是,CSubPanel这个类是在一个静态库工程中,UI_Widget和UI_Base都
Link了这个lib,而Exe直接调用的是UI_Widget。我写了个测试程序,两个dll直接静链MFC,在进入
MFC基类时,就不再跳转到子类所在模块了。

PS:之所以不使用MFC扩展dll,是因为它只能使用共享方式链接MFC,这就使得程序的运行环境
必须安装VS的发布包。只是想减掉这个包袱罢了。
...全文
115 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 4 楼 WindsonZhL 的回复:
[quote=引用 3 楼 draculacsdn 的回复:] 为何不在C1中重载CreatePanel,应该能解决问题
是可以,但是这个重载从设计上说没有意义。[/quote] 更关键的问题是,基类模块里的ModuleState和资源句柄处理如果去掉也是不合适的。 另外,每个子类都要重载一下,也有点麻烦了,呵呵。
  • 打赏
  • 举报
回复
引用 2 楼 Saleayas 的回复:
DLL 中的 资源是需要切换的。
是的,我上面已经分析了,只是这种意外的跳转是没有时机做切换的。
  • 打赏
  • 举报
回复
引用 3 楼 draculacsdn 的回复:
为何不在C1中重载CreatePanel,应该能解决问题
是可以,但是这个重载从设计上说没有意义。
draculacsdn 2015-07-30
  • 打赏
  • 举报
回复
为何不在C1中重载CreatePanel,应该能解决问题
Saleayas 2015-07-30
  • 打赏
  • 举报
回复
DLL 中的 资源是需要切换的。
  • 打赏
  • 举报
回复
我这个问题只想到一个解法,就是将UI_Base改成静态库工程。

16,482

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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