实例目的
如果要编写模块化的软件,就会对动态链接库(DLL)非常感兴趣。虽然C++类也是模块,但类是“创建时”模块,而DLL是“运行时”模块。在编写大的EXE程序时,每次修改后,都要重新编译,如果采用较小的DLL模块,则可以单独进行调试。MFC库支持两种DLL:扩展DLL和常规DLL。前者支持C++接口,后者可以被任意的Win32编程环境加载但不能导出C++类。本例制作一个扩展的DLL,导出CTest类(由CDialog类派生)。并创建另一个程序mTest来测试生成的DLL。
实现方法
客户程序搜索DLL的顺序为:包含EXE文件的目录;进程的当前目录;Windows系统目录;Windows目录;列在Path环境变量中的目录。因此,生成的DLL文件最好拷贝到测试程序所在的目录。要注意的是,每次重新建立DLL后,不要忘记重新拷贝到测试程序所在的目录,否则,测试程序加载的仍然是DLL的旧版本!
建立DLL的主要步骤如下:
1. 创建一个名为MFCDLL的扩展dll工程;
2. 在工程中新建CTest类,由CDialog派生。
3. 在MFCDLL.cpp中添加接口函数Show,该函数创建一个CTest类的模态对话框;
4. 编译运行,生成MFCDLL.dll文件
建立测试程序的主要步骤如下:
1. 创建一个基于对话框的工程;
2. 添加“测试”按钮,其消息处理函数显示链接MFCDLL.dll,从中导入Show函数。
程序代码
1. 创建一个名为MFCDLL.dll工程,接下来选择“Regular Dll using shared MFC DLL”即扩展DLL,其他选项接受默认设置。
2. 添加一对话框资源到工程中,从菜单中选择Insert->Resource,添加一个Dialog,标题改为“成功”,删除“确定”按钮,将“取消”按钮的标题改为“退出”。
3. 利用ClassWizard为对话框添加一个新类CTest,指定其基类为CDialog,该类与刚才创建的对话框资源相关联。
4. 在MFCDLL.cpp中添加接口函数Show,该函数创建一个CTest类的对话框:
extern "C" __declspec(dllexport) void Show()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTest test;
test.DoModal ();
}
5. 在MFCDLL.h中添加CTest类的头文件
#include "Test.h"
6. 用AppWizard新建一个名为mTest的对话框工程,编辑对话框资源,将确定按钮标题改为“测试”,建立ID_OK的消息映射函数OnOK,在此函数中显示链接MFCDLL并导入Show函数,添加的代码如下:
void CTestDlg::OnOK()
{
// TODO: Add extra validation here
typedef void (WINAPI * TESTDLL)();
HINSTANCE hmod;
hmod = ::LoadLibrary ("mfcdll.dll");
if(hmod == NULL)
{
MessageBox("链接失败。请检查是否包含了MFCDLL.dll文件。", "失败", MB_OK);
}
TESTDLL lpproc;
lpproc = (TESTDLL)GetProcAddress (hmod, "Show");
if(lpproc != (TESTDLL)NULL)
(*lpproc)();
FreeLibrary(hmod);
}
6. 编译运行,得到mTest.exe可执行文件。
7. 编译运行MFCDLL工程中,得到MFCDLL.dll文件,拷贝到mTest.exe所在的目录。(注意第一次运行调试程序时,调试程序会询问客户exe文件的路径,此后每次从调试程序运行DLL时,调试程序便加载该exe文件。)再次运行mTest.exe,选择“测试”按钮,即可弹出一个对话框,标题为“成功”,表示DLL的测试成功了。如果加载DLL时出现错误,则弹出链接失败的提示对话框。