Visual C++实用教程 教学课件 ppt 作者 周进 朱训林 张宏林 第11章-动态链接库

上传人:E**** 文档编号:89428337 上传时间:2019-05-25 格式:PPT 页数:102 大小:1.29MB
返回 下载 相关 举报
Visual C++实用教程 教学课件 ppt 作者  周进 朱训林 张宏林 第11章-动态链接库_第1页
第1页 / 共102页
Visual C++实用教程 教学课件 ppt 作者  周进 朱训林 张宏林 第11章-动态链接库_第2页
第2页 / 共102页
Visual C++实用教程 教学课件 ppt 作者  周进 朱训林 张宏林 第11章-动态链接库_第3页
第3页 / 共102页
Visual C++实用教程 教学课件 ppt 作者  周进 朱训林 张宏林 第11章-动态链接库_第4页
第4页 / 共102页
Visual C++实用教程 教学课件 ppt 作者  周进 朱训林 张宏林 第11章-动态链接库_第5页
第5页 / 共102页
点击查看更多>>
资源描述

《Visual C++实用教程 教学课件 ppt 作者 周进 朱训林 张宏林 第11章-动态链接库》由会员分享,可在线阅读,更多相关《Visual C++实用教程 教学课件 ppt 作者 周进 朱训林 张宏林 第11章-动态链接库(102页珍藏版)》请在金锄头文库上搜索。

1、第11章 动态链接库,动态链接库(Dynamic Link Librar,DLL)是一个可执行模块,其包含的函数可以由Windows应用程序调用以执行一些功能,主要为应用程序模块提供服务。 本章将全面、系统地阐述在Visual C+平台下进行Win32动态链接库的设计和应用。主要内容如下。, 动态链接库(DLL)的基础知识。 DLL的出入口函数。 调用DLL中的两种方式。 开发DLL的方式。 DLL中资源的利用。,11.1 动态链接库的基础知识,比较大的应用程序都是由很多模块组成的,这些模块彼此协作,以完成整个软件系统的工作。 其中可能存在一些模块的功能较为通用,在构造其他软件系统时仍会被使用

2、。,在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE文件中,会产生一些问题。,一是增加了应用程序的大小,占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另外,在编写大的EXE程序时,每次修改重建时都必须调整编译所有源代码,不但增加了编译过程的复杂性,也不利于阶段性的单元测试。,Windows系统平台上提供了一种完全不同的有效编程和运行环境,可以将独立的程序模块创建为较小的动态链接库文件,并可对它们单独进行编译和测试。 在运行时,只有在EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。,这种方式不仅减少了EXE文件的大小和

3、对内存空间的需求,而且这些DLL模块可以同时被多个应用程序使用,从而充分利用资源。,Microsoft Windows将一些主要的系统功能以DLL模块的形式实现。 例如,IE中的一些基本功能就是由DLL文件实现的,它可以被其他应用程序调用和集成。,一般来说,下面的这几种情况必须用到动态链接库技术。 多个应用程序共享代码和数据就是通过共享动态链接库实现的,比如Office软件的各个组成部分有相似的外观和功能。 在钩子程序过滤系统消息时必须使用动态链接库。 设备驱动程序必须是动态链接库。, 如果要在对话框编辑器中使用自己定义的控件,也必须使用动态链接库。, 动态链接库以一种自然的方式将一个大的应用

4、程序划分为几个小的模块,有利于小组内部成员的分工与合作。 而且,各个模块可以独立升级。 如果小组中的一个成员开发了一组实用示例,他就可以把这些示例放在一个动态链接库中,让小组的其他成员使用。, 为了实现应用程序的国际化,往往需要使用动态链接库。 使用动态链接库可以将针对某一国家、语言的信息存放在其中。 对于不同的版本,使用不同的动态链接库。 在使用AppWizard生成应用程序时,可以指定资源文件使用的语言,这就是通过提供不同的动态链接库实现的。,一般来说,DLL是一种磁盘文件(通常带有DLL扩展名),它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分

5、。,如果与其他DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。 DLL模块中包含各种导出函数,用于向外界提供服务。 Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。,在Win32环境中,每个进程都复制了自己的读写全局变量。 如果想要与其他进程共享内存,必须使用内存映射文件或者声明一个共享数据段。 DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。,DLL现在越来越容易编写。 Win32已经大大简化了其编程模式,并有许多来自AppWizard和MFC类库的支持。 使用Visual C+ 6.0工具可以编写3种不同类型的动态链接库。, Non-MF

6、C DLL:指不用MFC的类库结构,直接用C语言编写的DLL,其输出的函数一般采用标准C接口,并能被非MFC或MFC编写的应用程序所调用。, Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。 其特点是在源文件里有一个继承CWinApp的类。,其又可细分成静态连接到MFC和动态连接到MFC上的。 但静态连接到MFC的动态链接库只被Visual C+的专业版和企业版所支持。, Extension DLL:用来实现从MFC所继承下来的类的重新利用,也就是说,用这种类型的动态链接库,可以用来输出一个从MFC所继承下来的类。 Extension DLL使用MFC的

7、动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。,11.2 DLL的出入口函数,DllMain()函数是DLL模块的默认入口点。 当Windows加载DLL模块时调用这一函数。 系统首先调用全局对象的构造函数,然后调用全局函数DllMain()。 DllMain()函数不仅在将DLL链接加载到进程时被调用,在DLL模块与进程分离时(以及其他时候)也被调用。,DLL文件中包含一个导出函数表。 这些导出函数由它们的符号名和标识号的整数与外界联系起来。 函数表中还包含了DLL中函数的地址。,当应用程序加载DLL模块时,它并不知道调用函数的实际地址,但它知道函数的符号名和标识号。

8、动态链接过程在加载DLL模块时动态建立一个函数调用与函数地址的对应表。,如果重新编译和重建DLL文件,并不需要修改应用程序,除非改变了导出函数的符号名和参数序列。,简单的DLL文件只为应用程序提供导出函数,比较复杂的DLL文件除了提供导出函数以外,还调用其他DLL文件中的函数。,这样,一个特殊的DLL既有导入函数,又有导出函数。 这并不是一个问题,因为动态链接过程可以处理交叉相关的情况。,在DLL代码中,声明导出函数的代码如下。 _declspec(dllexport) int MyFunction(int n);,11.2.1 DllMain()函数 每一个DLL必须有一个入口点,这就像用C

9、语言编写的应用程序一样,必须有一个WinMain函数一样。,在Non-MFC DLL中DllMain()是一个默认的入口函数,不需要编写自己的DLL入口函数,用这个默认的入口函数就能使动态链接库在被调用时初始化。,如果应用程序的DLL需要分配额外的内存或资源,即对每个进程或线程初始化和清除操作时,就需要在相应的DLL工程的CPP文件中对DllMain()函数按照下面的格式书写,代码如下。,11.2.2 DLL的导出函数 当C/C+编译器看到变量、函数原型或C+类之前的这个修改符的时候,它就将某些附加信息嵌入产生的.obj文件中。 当链接DLL的所有.obj文件时,链接程序将对这些信息进行分析。

10、,当DLL被链接时,链接程序要查找关于输出变量、函数或C+类的信息,并自动生成一个.lib文件。 该.lib文件包含一个DLL输出的符号列表。,当然,如果要链接引用该DLL的输出符号的任何可执行模块,该.lib文件是必不可少的。 除了创建.lib文件外,链接程序还要将一个输出符号表嵌入产生的DLL文件。,这个输出节包含输出变量、函数和类符号的列表(按字母顺序排列)。 该链接程序还将能够找到每个符号的相对虚拟地址(RVA),并在该地址中放入DLL模块。,使用Visual Studio的DumpBin.exe实用程序(带有-exports开关),能够看到DLL的输出节是个什么样子。 Kernel3

11、2.dll的输出结果如图11-1所示。,图11-1 dumpbin输出动态链接库的导出函数,通过Visual Studio所提供的Dependency Walker的可视化工具也可以查看动态链接库的导出函数信息,如图11-2所示。,图11-2 利用Dependency Walker工具查看导出函数信息,11.3 两种链接DLL的方式,如果线程需要调用DLL模块中的函数,那么DLL文件映像必须映射到调用线程的进程地址空间中。 可以用两种方法进行这项操作。 第1种方法是让应用程序的源代码只引用DLL中包含的符号。,这样,当应用程序启动运行时,加载程序就能够隐含加载(或链接)需要的DLL。 第2种方

12、法是在运行时让应用程序显式加载需要的DLL并且显式链接到需要的输出符号。,换句话说,当应用程序运行时,其中的线程决定它是否要调用DLL中的函数。 该线程可以将DLL显式加载到进程的地址空间,获得DLL中包含的函数的虚拟内存地址,然后使用该内存地址调用该函数。,该方法的一切操作都是在应用程序运行时进行的。 当线程加载动态链接库的时候,是按照下面的搜索顺序查找并加载动态链接库文件的。, 当前目录下(首先将动态链接库复制至DEBUG目录下,因为可执行文件在该目录下)。 Windows目录。 Windows系统目录。 PATH环境变量中设置的目录。 列入映射网络的目录表中的目录。,11.3.1 隐式链

13、接 如果程序员采用隐式链接方式建立一个DLL文件,链接程序会自动生成一个与之对应的LIB导入文件。 该文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。,LIB文件作为DLL的替代文件被编译到应用程序项目中。 当程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入生成的EXE文件中。,LIB文件中也包含了对应的DLL文件名(但不是完全的路径名),链接程序将其存储在EXE文件内部。 当应用程序运行过程中需要加载DLL文件时,Windows根据这些信息发现并加载DLL,然后通过符号名或标识号实现对DLL函数的动

14、态链接。,11.3.2 显式链接 显式链接方式对于集成化的开发语言(如Visual Basic)比较适合。,有了显式链接,程序员就不必再使用导入文件,而是直接调用Win32的LoadLibary函数,并指定DLL的路径作为参数。 LoadLibary返回HINSTANCE参数,应用程序在调用GetProcAddress函数时使用这一参数。,GetProcAddress函数将符号名或标识号转换为DLL内部的地址。 假设有一个导出如下函数的DLL文件。 extern “C“ _declspec(dllexport) double SquareRoot(double d);,在隐式链接方式中,所有被

15、应用程序调用的DLL文件都会在应用程序EXE文件加载时被加载到内存中。 但如果采用显式链接方式,程序员可以决定DLL文件何时加载或不加载。,显式链接在运行时决定加载哪个DLL文件。 例如,可以将一个带有字符串资源的DLL模块以英语加载,而另一个以西班牙语加载。 应用程序在用户选择了合适的语种后再加载与之对应的DLL文件。,在显式链接方式中,应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接无法做到的,所以显式链接具有更好的灵活性,更适合解释性语言。,不过实现显式链接比较复杂,除了要调用特定的Win32的LoadLibrary函数动态链接DLL,在应用程序退出之前

16、,还应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。,11.4 开发DLL,在Visual C+ 6.0开发环境下,打开“FileNewProject”选项,可以通过选择Win32 Dynamic-Link Library或MFC AppWizarddll的不同方式来创建Non-MFC DLL、Regular DLL、Extension DLL等不同种类的动态链接库。,11.4.1 创建Non-MFC DLL动态链接库 关于DllMain()函数,在11.2.1节中已经作了详细介绍,这里不再赘述。,DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。,要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义DEF文件

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号