动态链接库:
l 系统预安装的DLL,如KERNEL32。DLL和USER32。DLL等
l 当前目录
l Windows的系统的目录,如WINNTsystem32
l Windows所在的目录,如WINNT
l 环境变量PATH中所指定的目录
…………………………………………………………Page 673……………………………………………………………
图13。2 tester应用程序的运行结果
如果Windows在上面的目录中未找到所需要的DLL,则弹出如图13。1所
示的对话框。这里,我们把msgbox。dll文件拷贝到testerDebug 目录
下,再运行应用程序,则出现如图13。2所示的对话框。
(2) 使用显式链接
如果没有与DLL相关联的LIB文件,则必须使用显式链接。使用显式链
接同样必须知道函数返回值的类型和所传递的参数个数、类型和顺
序。与使用隐含链接不同的是,使用显式链接的应用程序在调用DLL
中的导出函数前,必须使用LoadLibrary()函数加载DLL并得到一个模
块句柄。然后使用该句柄调用GetProcAddress()函数获得所需调用的
导出函数的指针,并通过该指针调用DLL中的导出函数,这种模式使
用显式链接到DLL的应用程序不再需要相应的LIB文件。在使用完毕之
后,还需调用FreeLibrary()函数释放加载的DLL。
下面我们使用显式链接的方式来实现前面的例子。
由于使用指针来调用DLL中的导出函数,所以本例中不再需要
msgbox。h文件。
在tester。cpp中添加的代码如下所示:
#include
typedef int (CALLBACK* DLLFUNC)(
LPCTSTR lpText=〃虽然这个例子有一些简单,但它工作得非常的好 !〃;
LPCTSTR lpCaption=〃一个简单的例子〃;
UINT=MB_OK);
int WINAPI WinMain(HINSTANCE hInstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow)
{
…………………………………………………………Page 674……………………………………………………………
HINSTANCE hDLL;
DLLFUNC MsgBox;
hDLL = LoadLibrary(〃msgbox〃);
if (hDLL != NULL)
{
MsgBox =
(DLLFUNC)GetProcAddress(hDLL;〃MsgBox〃);
return MsgBox();
}
}
LoadLibrary()函数的参数是所调用的DLL的名字,这个名字不是放入
输入库文件中的名字,而是DLL的文件名。如果文件的扩展名
为。DLL,则可以省略。
这个程序的运行结果同使用隐含链接的前一个程序一样,但它的内部
实现是很不相同的。使用显式链接的应用程序加载时,所调用的DLL
并不加载,只有当应用程序调用LoadLibray()时系统才加载相应的
DLL,并在应用程序调用FreeLibrary()时卸载该DLL。使用隐含链接
的应用程序调用DLL中的导出函数时,方法同调用一般的函数一样,
而使用显式链接的应用程序必须使用指针来调用。由于使用了指针,
因此在编译时不能验证参数的合法性,通过指针使用不合法的参数来
调用DLL中的导出函数将会导致不可预料的后果。
很明显,使用隐含链接的方式调用DLL中的导出函数要比使用显式链
接方便得多。但在某些情况下我们必须使用显式链接。事实上,使用
显式链接调用DLL提供了更大的灵活性。尤其在没有与DLL相对应的
LIB文件时,我们只能使用显式链接来调用DLL中的导出函数,并且,
只要我们使用函数名作参数来调用GetProcAddress(),在更新DLL
时,就没有必要重新链接应用程序。另外,使用隐含链接的方式的应
用程序加载DLL时如果发生错误 (如DLL文件未找到或是DLL中的
DllMain()函数初始化失败)时,应用程序将被终止,而使用显式链
接的应用程序则可以使用如上面的例子中所给出的方法来避免出现这
种情况 (可以使用所创建的两个不同版本的tester程序来验证这一
点)。
…………………………………………………………Page 675……………………………………………………………
由于应用程序调用LoadLibrary()函数时才加载DLL,因此使用显式链
接的应用程序的加载速度要比使用隐含链接的应用程序快。使用显式
链接的另一个好处是,应用程序可以在运行时决定所加载的DLL。
但是要记住,由于使用了指针来传递应用程序的参数,因此编译器在
编译时无法确认应用程序所传递的参数类型是否合法。传递不合法的
参数给DLL中的导出函数的一件危险的事。在程序调试的过程中我们
一定需要注意这一点。
第三节 使用动态链接连库扩展MFC
我们还可以使用DLL来实现从MFC派生的一些可重用类,这种动态链接
库一般称作MFC扩展动态链接库 (MFC Extension DLL)。正如这个名称
所暗示的那样,通过这种方式我们可以扩展MFC所包括的内容,使得
使用MFC编程更加的方便。此外,如果需要在应用程序和DLL之间传递
MFC或者由MFC派生的对象的指针的话,我们也必须使用MFC扩展DLL。
在本节中,我们使用MFC扩展DLL来创建一个输入通用对话框,如图
13。3所示。该对话框很象Visual Basic中的InputBox函数所产生的对
话框,使用过Visual Basic的程序员都有印象,函数InputBox非常之
好用,这里,我们来使用动态链接库在Visual C++ 的MFC中也创建这
么一个好用的类。
图13。 3 输入通用对话框
输入通用对话框由类CInputDlg封装,类CInputDlg提供了一个公有成
员函数GetInput,该成员函数的原型如下:
CString GetInput(CString Title; CString Prompt)
第一个参数Title表示输入对话框的标题,在图13。3中为 “输入”;
第二个参数Prompt代表在输入对话框中显示的简短提示文本,在图
13。3中为 “请输入对话框的标题:”。函数的返回值为用户在对话框
的文本框中输入的字符串。如果用户没有输入任何字符串或者单击了
“取消”按钮,返回值为空串〃〃。
下面我们来介绍该对话框的创建和使用。首先讲述DLL工程
ExtDllDemo的创建。该工程实现了类CInputDlg的导出。
…………………………………………………………Page 676……………………………………………………………
1。 使用AppWizard创建一个MFC扩展DLL工程,将工程取名为
ExtDllDemo。
2。 向工程中添加一个对话框资源IDD_INPUT,按图13。3绘制对话框中
的各控件。这些控件的资源ID如表所示。
表13。 1 对话框资源IDD_INPUT中的控件属性
控件 资源ID
提示文本 IDC_PROMPT
标签
输入文本 IDC_EDIT
框
3。 使用ClassWizard为对话框资源IDD_INPUT创建新的对话框类
CInputDlg,该类直接派生于CDialog。按下面的代码修改类
CInputDlg的头文件和实现文件。
#if !defined(AFX_INPUTDLG_H__02DB98CF_1F76_11D2_971A_0000B4810A31__INCLUDED_)
#define AFX_INPUTDLG_H__02DB98CF_1F76_11D2_971A_0000B4810A31__INCLUDED_
#if _MSC_VER 》= 1000
#pragma once
#endif // _MSC_VER 》= 1000
// InputDlg。h : 头文件
//
// 以下对话框 ID 常量需要手动添加
#define IDC_EDIT 1000
#define IDC_PROMPT 1001
#defin
小说推荐
- C语言游戏编程从入门到精通(PDF格式)
- -Page 1-Page 2-Page 3-Page 4-Page 5-Page 6-Page 7-Page 8-Page 9-Page 10-Page 11-Page 12-Page 13-Page 14
- 其他
- 最新章:第4章
- JMS简明教程(PDF格式)
- -Page 1-JMS1.1规范中文版卫建军2007‐11‐22-Page 2
- 其他
- 最新章:第28章
- SQL语言艺术(PDF格式)
- -Page 1-SQLSSQQLL语言艺术内容介绍本书分为12章,每一章包含许多原则或准则,并通过举例的方式对原则进行解释说明。这些例子大多来自于实际案例,对九种SQL经典查询场景以及其性能影响讨论,非常便于实践,为你数据库应用维护人员阅读。资深 SQL 专家 Stéphane Faroult倾力打
- 其他
- 最新章:第27章
- 软件工程实践者的思想(PDF格式)
- -Page 1-大 道 至 简—软件工程实践者的思想周爱民(Aimingoo 著-Page 2-序2004 年 11 月初爱民(Aimingoo)第一次把他的书稿给我,我翻看了一下,第一反应讲的是感想。这不错,在技
- 其他
- 最新章:第26章
- asp基础实用教程(DOC格式)
- 目 录一、关于ASP二、ASP的新功能三、创建ASP页四、使用脚本语言五、使用变量和常量六、使用集合七、ASP内建对象八、向浏览器发送内容九、包含文件十、访问数据库十一、调试ASP脚本十二、维护ASP应用程序的安全一、关于ASP Active Server Pages(ASP)是服务器端脚本编写环境
- 其他
- 最新章:第17章
- Linux实用培训教程(PDF)
- -Page 1-rrktqt的个人空间 Linux实用培训教程第一部分 作者:红联Linux实用培训教程第一部分-共三部分解的Linux知识,循序渐进的介绍Linux相关知识,从入门到提高,希望对所有学习Linux的朋友都有帮助 红联Linux论坛是致力于Linux技术讨论的站点,目前网站收录的文章
- 其他
- 最新章:第42章
- php程序设计简明教程(DOC格式)
- -Page 1-PHP 程序设计简明教程PHP 讲义 第 1 页 共 90 页-Page 2-目录序 4第一章 PHP 简介 6
- 其他
- 最新章:第31章
- 路由器基本知识及应用实例(DOC格式)
- 第二章 路由器第一节 路由器发展概述自从1984年问世至今,路由器已经走过了近20年的快速技术发展历程。路由器的应用领域不断扩展、从单一的互通网关逐渐扩展到覆盖广域网、城域网乃至用户接入的各个领域。近年来,路由器早已逐渐脱离单纯用于企业网出口和互联的概念,开始成为运营网络和各种专用业务网络的核心设备
- 其他
- 最新章:第48章
- Java编程思想第4版[中文版](PDF格式)
- -Page 1-Page 2《Thinking In Java》中文版作者:Bruce Eckel主页:http/BruceEckel.编译:Trans Bot主页:http/memberease~transbot致谢-献给那些直到现在仍在孜孜不倦创造下一代计算机语言的人们!指导您利用万维网的语言进
- 其他
- 最新章:第295章