关于dll中的资源问题

转载 2013年12月05日 18:43:31

原文链接:http://tech.163.com/06/0316/10/2CB1FGNG0009159F_4.html

先看一个例子:

1、创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源。指定该对话框ID如下:
              #define IDD_DLL_DIALOG2000

2、创建一个基于对话框的mfc应用程序,它包含两个对话框资源,IDD_UI_DIALOG和IDD_EXE_DIALOG。并将后者的ID指定如下:
              #define IDD_EXE_DIALOG2000
其中前者是这个应用程序的用户界面,单击上面的按钮,将弹出一个对话框。部分代码如下:
// in DLL
void CDLL::ShowDlg(void)
{
       CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
       dlg.DoModal();
}
// in EXE
void CEXE::OnButtonClick()
{
       ShowDlg();
}

3、单击按钮,弹出的不是期望的DLL中的对话框IDD_DLL_DIALOG,而是应用程序中的对话框IDD_EXE_DIALOG。

解释:

1、应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,它们代表了EXE或DLL模块在进程虚拟空间中的起始地址。(进程本身的模块句柄一般为0x400000,而DLL模块的缺省句柄为0x10000000。如果程序同时加载了多个DLL,则每个DLL模块都会有不同的HINSTANCE。应用程序在加载DLL时对其进行了重定位)。
2、共享MFC DLL(或MFC扩展DLL)的规则DLL涉及到HINSTANCE句柄问题,HINSTANCE句柄对于加载资源特别重要。EXE和DLL都有其自己的资源,而且这些资源的ID可能重复,如果应用程序与规则DLL共享MFC DLL(或MFC扩展DLL),那么将总是默认使用EXE的资源
3、因此应用程序需要通过资源模块的切换来找到正确的资源。如果应用程序需要来自于DLL的资源,就应将资源模块句柄指定为DLL的模块句柄;如果需要EXE文件中包含的资源,就应将资源模块句柄指定为EXE的模块句柄。

解决办法:

1、在DLL中改进:

方法1。

// in DLL
void CDLL::ShowDlg(void)
{
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
       dlg.DoModal();
}

注:AFX_MANAGE_STATE(AfxGetStaticModuleState());一定是作为接口函数的第一条语句。
       其功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类的实例,并将其指   针pModuleState返回。
       AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作。
       该宏用于将pModuleState设置为当前的有效模块状态。当离开该宏的作用域时(也就离开了pModuleState所指栈上对象的作用域),先前的模块状态将由类AFX_MODULE_STATE的析构函数恢复。(即自动恢复)

方法2。

// in DLL
void CDLL::ShowDlg(void)
{
       HINSTANCE save_hInstance = AfxGetResourceHandle();
       AfxSetResourceHandle(theApp.m_hInstance);
       CDialog dlg(IDD_DLL_DIALOG); //打开ID为2000的对话框
       dlg.DoModal();
      AfxSetResourceHandle(save_hInstance);    
}

注:AfxGetResourceHandle:获取当前资源模块句柄;AfxSetResourceHandle:设置程序目前要使用的资源模块句柄。
       同方法1比较,方法2能够灵活地设置程序的资源模块句柄,而方法1则只能在DLL接口函数退出的时候才会恢复模块句柄。

2、在应用程序中改进:

// in EXE
void CEXE::OnButtonClick()
{
       HINSTANCE exe_hInstance = GetModuleHandle(NULL);
      HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");
      AfxSetResourceHandle(dll_hInstance); //切换状态
       ShowDlg();
      AfxSetResourceHandle(exe_hInstance); //恢复状态
}

注:使用状态切换的情况:当DLL导出函数包含MFC资源、类或者需要创建窗口时。

 

关于AFX_MANAGE_STATE(AfxGetStaticModuleState());解释的一片文章:http://blog.csdn.net/kafeiwuzhuren/article/details/7327313

C#嵌入dll到资源释放的问题

有些程序的时候,可能调用外部的dll,这个时候提供给客户的时候,可能经常不小心丢失这些dll,因此可以考虑将这些dll嵌入到资源中,启动的时候进行释放。对于托管的dll,可以用打包软件合成一个exe(...
  • kikaylee
  • kikaylee
  • 2015年03月22日 11:50
  • 7975

解决duilib使用zip换肤卡顿的问题(附将资源集成到程序中的操作方法)

转载请说明原出处,谢谢~~   是
  • zhuhongshu
  • zhuhongshu
  • 2014年10月16日 13:04
  • 5449

如何解决java线程中的资源共享的问题

更多相关的文章的链接:http://www.cnblogs.com/chenssy/p/4701027.html; 1.资源共享问题的产生:由于需要被访问的资源没有被合理地保护起来,所以在多线程都来访...
  • li12412414
  • li12412414
  • 2016年05月18日 21:41
  • 1265

[WPF] 嵌入资源到DLL,并解决PNG图片问题

在WPF有很多种资源文件存储的方式,就图片的存储就麻烦到极点。 最近自己弄一个项目就遇到这样那样的问题,现在把自己的使用方法总结出来给大伙借鉴借鉴! 在我的项目中,我并不想把所有的图片都存放在文件夹下...
  • qiujuer
  • qiujuer
  • 2014年01月06日 16:46
  • 4312

MFC + 线程访问窗口资源的问题(规则DLL)

我们在设计平台类应用程序时,常常会受到一些特殊UI的影响,例如,在一个算法平台中,要加入一个特殊算法的配置对话框,这时,平台维护工程师,肯定不想把这个对话框放在平台中,一是当前的对话框压根和当前模块的...
  • Alexander_Frank
  • Alexander_Frank
  • 2016年08月09日 16:45
  • 568

MFC扩展dll里导出函数时资源切换的问题

在MFC扩展dll里导出函数时应该也进行资源的切换。 在共享的(动态链接的)MFC规则dll里,在每一个导出函数前都需进行资源的切换,在扩展dll里同样也需要,因为它们都是动态链接到MFC库 的,...
  • Matrix_Designer
  • Matrix_Designer
  • 2011年04月20日 14:21
  • 917

扩展 DLL资源冲突问题

平时比较少把对话框之类的资源打包到DLL中,基本都是放一些逻辑算法,所以感觉用起来也顺手,没多少难度.这几天特地把一些项目进行优化,其中需要把一个带对话框的功能模块化,随即轻车熟路的用VS 2010创...
  • Banket004
  • Banket004
  • 2013年10月22日 17:54
  • 1304

DLL导出资源问题的解决

以前写MFC的DLL的时候,总会在自动生成的代码框架里看到提示,需要在每一个输出的函数开始添加上AFX_MANAGE_STATE(AfxGetStaticModuleState())。一直不明白这样做...
  • wang_harry
  • wang_harry
  • 2011年10月24日 22:34
  • 168

C#嵌入dll到资源释放的问题

http://blog.csdn.net/kikaylee/article/details/44536231  有些程序运行的时候,可能调用外部的dll,用户使用时可能会不小心丢失这...
  • mosangbike
  • mosangbike
  • 2017年01月18日 09:29
  • 1197

C#嵌入dll到资源释放的问题

有些程序运行的时候,可能调用外部的dll,用户使用时可能会不小心丢失这些dll,导致程序无法正常运行,因此可以考虑将这些dll嵌入到资源中,启动时自动释放。对于托管的dll,我们可以用打包软件合成一个...
  • wangyinlon
  • wangyinlon
  • 2017年01月26日 10:15
  • 307
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于dll中的资源问题
举报原因:
原因补充:

(最多只允许输入30个字)