文章相关视频教程下载地址http://pan.baidu.com/s/1mhKxdbU
3 共享链接的MFC规则动态库
对比静态链接,共享链接的MFC规则动态库所占的体积较小。但是在使用后者中的资源时,需要进行模块切换。
3.1 模块切换
应用程序进程本身及其调用的每个DLL模块都具有一个全局唯一的HINSTANCE句柄,这些句柄代表了进程模块或DLL模块在虚拟空间中的起始地址。对于调用共享链接的MFC规则动态库的程序,其资源模块句柄默认是进程模块句柄,即DLL模块的起始地址也默认为进程模块地址,而不是DLL模块本身的起始地址。因此,如果调用动态库的应用程序要使用动态库中的资源,需要将资源句柄指定为DLL的模块句柄。这就是所谓的模块切换。
3.2 创建动态库
创建共享链接的MFC规则动态库的方法与创建静态链接的MFC规则动态库的方法类似,区别在于图2中选择“使用共享MFC DLL的规则DLL”而不是“带静态链接MFC的规则DLL”。
与“2.2 编写动态库”中介绍的方法相同,为动态库添加一个对话框和一个导出函数ShowDialog(),该函数的功能是显示对话框,并将对话框的“Caption”设置为“DLL程序的对话框”。该动态库的名称为MFC_Regular_Share_DLL_Test.dll。
此时,双击“解决方案资源管理器”中的“Resource.h”头文件,查看添加的对话框资源ID为5000,如图5所示。
图5 查看对话框资源ID
3.3创建调用动态库的程序
创建一个基于对话框的MFC程序,在该对话框中添加一个按键,当按下该按键后,使用动态的方式加载MFC_Regular_Static_DLL_Test.dll,代码如下所示
HINSTANCE hDll;
hDll = LoadLibrary(_T("MFC_Regular_Share_DLL_Test.dll"));
if (hDll == NULL)
{
MessageBox(_T("导入动态库失败"));
return;
}
lpFun pShowDialog = (lpFun)GetProcAddress(hDll, "ShowDialog");
if (pShowDialog == NULL)
{
MessageBox(_T("搜索函数地址失败"));
return;
}
pShowDialog();
接下来,为该MFC程序添加一个对话框资源,将该对话框资源的“Caption”设置为“调用DLL程序的对话框”,以区别DLL中的对话框资源。之后,为新添加的对话框资源添加相应的类。
双击MFC程序的“解决方案资源管理器”中的“Resource.h”头文件,将新添加的对话框ID的值修改为在“3.2创建动态库”中提到的动态库对话框ID的值,即5000,如图6所示。
图6 修改对话框资源的ID值
将MFC_Regular_Static_DLL_Test.dll拷贝到MFC程序源代码所在的路径下,之后运行该MFC程序,点击按键后弹出的对话框并不是DLL中的对话框而是MFC程序中的对话框,如图7所示。
图7 弹出的对话框为MFC程序中的对话框
产生上述情况的原因即为在“3.1模块切换”中提到的,对于调用共享链接的MFC规则动态库的程序,其资源模块句柄默认为进程模块地址。因此,此时显示的是进程模块地址中ID为5000的对话框资源,而不是DLL模块地址中ID为5000的对话框资源。
2570

被折叠的 条评论
为什么被折叠?



