dll调用dll,dll文件的使用

  dll调用dll,dll文件的使用

  很久以前我写过关于MFC中CDialog和它的对话框资源的绑定,但是这几天做了一些MFC DLL的工作,发现当时的理解真的很肤浅。也许若干年后,我再回头看现在的这篇文章,会觉得这篇文章全是废话,哈哈。

  在DLL中使用资源的一个主要问题是,DLL和EXE中都有资源集,但这常常让我们怀疑程序在运行时会寻找哪个资源集。

  考虑以下经典案例:

  创建新的MFC DLL项目时选择使用共享MFC DLL的常规DLL选项,并创建一个与MFC自己的DLL共享的新DLL。在新DLL中创建一个名为IDD_DLLDIALOG的新对话框资源。导出此DLL中包含以下内容的ShowDialog()函数:

  新建一个MFC EXE项目,导入新建dll项目的lib和DLL,设置OK按钮的响应函数为:ShowDialog();链接编译好之后,当我们运行程序的时候,会发现点击确定按钮后没有任何响应!为什么.我们不是在DLL里明确设置了IDD_DLLDIALOG吗?在构建新的MFC dll项目时,请注意“使用共享MFC dll的常规DLL”这句话。如果我们当时选择“MFC静态链接的常规dll”会怎么样?又可以正常显示了!

  使用静态连接访问MFC库DLL会将MFC库DLL与项目本身打包在一起,而共享会在运行时将MFC库DLL动态加载到系统路径中。我们可以这样理解上面的现象:如果新创建的DLL以共享的方式访问库DLL,那么EXE程序运行时,实际上有两套上下文系统在运行,而静态连接只有一套上下文系统,所以静态连接时会需要切换模块状态。

  当我们的新DLL是共享访问库DLL时,解决上述问题的常用方法是在ShowDialog函数中增加一句afx _ manage _ state(afxgetstaticmodulestate());

  AfxGetStaticModuleState()的原型是:

  AFX _ MODULE _ STATE * AFX API AfxGetStaticModuleState();

  即当前模块的ModuleState指针。

  Af _ manage _ state宏将在堆栈上创建一个新类,以传入的指针作为参数。你可以猜到这个类会做什么。没错,它会将当前ThreadState指向的ModuleState指针保存在构造函数中,然后将传入的指针指定为当前ThreadState指向的指针。等到这个类的实例被析构后,再把它改回来。

  另一种方法是将AfxGetResourceHander()与AfxSetResourceHander(hin instance)结合使用(这正是我在MFC中CDialog及其对话框资源的绑定中介绍的方法)。

  如果我们不想在EXE中间接调用DLL导出的ShowDialog(),而是直接想在EXE的OnBnClickedOk()中使用DLL中的对话框资源生成对话框怎么办?此时afx _ manage _ state(afxgetstaticmodulestate())是没有用的(因为在DLL项目中使用)。最好的方法是将AfxSetResourceHander(HINSTANCE)与GetModuleHandle(LPCTSTR)一起使用。

  GetModuleHandle(LPCTSTR)会根据传入的字符串获取相应的模块句柄。注意,EXE和DLL都可以看作是模块。当传入为NULL时,将获得当前进程(EXE)的提示句柄。GetModuleHandle用于确保已加载相应的dll。也许你会说这个条件不是废话,但是真的很容易出错。

  如果dll是静态加载的(即生成的。lib文件直接导入),而且这个DLL中的任何函数或者变量之前都没有被调用过,GetModuleHandle只会得到一个空值。因为在某个语句调用dll的内容之前,系统不会真正加载dll。

  例如:

  上面的代码在运行时会报错,因为AfxSetResourceHandle在检查参数时发现了一个空值。下面的代码就可以了:

  其中TestOnly也是从RegDll导出的函数。它只返回1。我们只用它来加载RegDll。当然,如果我们直接用动态加载的方法,像下面这样直接加载库,也不会有问题。

  但是,眼尖的读者可能会马上发现,实际使用GetModuleHandle并不是上述情况下的最佳选择。因为直接的AfxSetResourceHandle(hm)可以解决问题。

  出发地:http://www.thankcreate.com/c/275

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • windows10缺少dll文件,win10运行时出错无法找到指定dll库文件
  • ,,详解VS2019 dumpbin查看DLL的导出函数
  • ,,解决采集时出现msxml3.dll 错误的方法
  • ,,使用 JScript 创建 .exe 或 .dll 文件的方法
  • ,,VC++ loadlibrary()加载三方dll失败, 返回错误码-126的解决方法
  • .net dll加密,c++ dll 反编译
  • .net dll加密,c++ dll 反编译,保护.net中的dll文件方法(防止破解、反编译dll)
  • .dll是什么文件能不能删除,文件dll怎么删除
  • dll没有在指定的windows上运行,xlivedll没有在windows上运行
  • 删除linkinfo.dll操作无法完成,因为已经在打开,linkinfo.dll是病毒吗
  • python能封装成dll文件吗,python自己封装的类怎么调用
  • 无法定位序数4445于动态链接库libcurl.dll,无法定位序数4445于动态链接库
  • d3dx9-43.dll文件丢失,d3dx9_41.dll文件丢失
  • igfxsrvc.exe木马病毒,igfxsrvc.dll加载失败_1
  • 怎么用360修复dll文件,360 dll文件修复
  • 留言与评论(共有 条评论)
       
    验证码: