《Visual C++程序设计教程》-梁建武-电子教案 第13章

上传人:E**** 文档编号:89409386 上传时间:2019-05-24 格式:PPT 页数:31 大小:120.50KB
返回 下载 相关 举报
《Visual C++程序设计教程》-梁建武-电子教案 第13章_第1页
第1页 / 共31页
《Visual C++程序设计教程》-梁建武-电子教案 第13章_第2页
第2页 / 共31页
《Visual C++程序设计教程》-梁建武-电子教案 第13章_第3页
第3页 / 共31页
《Visual C++程序设计教程》-梁建武-电子教案 第13章_第4页
第4页 / 共31页
《Visual C++程序设计教程》-梁建武-电子教案 第13章_第5页
第5页 / 共31页
点击查看更多>>
资源描述

《《Visual C++程序设计教程》-梁建武-电子教案 第13章》由会员分享,可在线阅读,更多相关《《Visual C++程序设计教程》-梁建武-电子教案 第13章(31页珍藏版)》请在金锄头文库上搜索。

1、第13章 动态链接库,13.1 DLL基础知识,本节讲述DLL的基础知识。,13.1.1 DLL概述,Windows系统平台上提供了一种完全不同的有效的编程和运行环境,可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。,13.1.2 认清DLL与LIB,DLL与LIB的

2、相似之处是它们都是将一部分可执行代码以及数据放在库中供用户程序使用,而且在使用时,这些代码就象是用户程序本身的一部分。 LIB文件是静态链接库文件,在其中放置了许多的函数和变量。其中一部分函数和变量是供内部使用的,在接口中不可见,即没有输出;另一部分是供接口使用的(当然内部函数也可以使用),外部可见,从而应用程序可以调用这些输出的函数和变量。 在DLL中同样包括许多变量和函数,也分为内部变量、函数和外部接口函数、变量。对于内部的函数和变量,供DLL自己调用,因此并不包含名称,只使用地址;对于供外部调用的函数和变量,在内部的时候也使用地址,只是在头文件中包含了输出变量和函数的名称,而且包含了这些

3、名称所对应的地址,即将名称和地址对应起来。通过这些名称就可以查找对应变量和函数的地址(函数的地址是指函数入口点的地址)。,13.1.3 认清DLL与EXE,DLL和EXE都是Windows下的可执行模块,在对应的文件结构上,它们也类似的:具有文件头,重定位信息表,导入动态库表等,另外,DLL作为供程序调用的服务者,文件中还包含导出的函数表和变量表。 DLL是服务的提供者,主要用来提供输出变量和函数供别的程序调用,在DLL被装入的时候,以及进程中创建线程的时候,Windows都会以不同的参数调用入口点函数,然后该函数进行某些初始化工作后返回,DLL的执行就停止了。Windows并不为DLL创建单

4、独的进程空间,而是将其装入共享地址,然后将其映射到不同的进程供进程调用,从而达到代码共享的目的。 EXE是DLL所提供服务的使用者,调用DLL中的输出的函数和变量,每一个EXE在运行的时候,Windows均为它创建单独的进程环境,包括进程地址空间,EXE就在它的地址空间中运行,对别的进程是不透明的,因此也就无法为别的进程调用,因此在许多情况下只能使用DLL来实现某些功能。,13.1.4 DLL的两种动态链接方法,加载时动态链接 由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用

5、时才释放它),简单实用,但不够灵活,只能满足一般要求。 运行时动态链接 是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。,13.2 DLL入/出口函数,Win32 DLL与 Win16 DLL有很大的区别,这主要是由操作系统的设计思想决定的。一方面,在Win16 DLL中程序入口点函数和出口点函数(LibMain和WEP)是分别实现的;而在Win32 DLL中却由同一函数DLLMain来实现。无论何时,当一个进程或线程载入和卸载DLL时,都要调用该函数。,13.2.1 DllMain函数,每一个DLL必须有一个

6、入口点,DLLMain是一个缺省的入口函数。DLLMain负责初始化(Initialization)和结束(Termination)工作,每当一个新的进程或者该进程的新的线程访问DLL时,或者访问DLL的每一个进程或者线程不再使用DLL或者结束时,都会调用DLLMain。但是,使用TerminateProcess或TerminateThread结束进程或者线程,不会调用DLLMain。,13.2.2 MFC AppWizard 生成的Regular DLL入出口,MFC AppWizard 生成的Regular DLL在后面的章节会有介绍,这里只讨论它的入/出口点问题。 每个Regular D

7、LL都有MFC AppWizard 自动生成的CWinApp派生类的对象,与其它MFC应用程序一样,它是在CWinApp派生类的成员函数InitInstance和ExitInstance完成初始化和终止的工作。 实际上,MFC提供了一个基本的DllMain函数,在这种DLL中不必自己编写DllMain函数,由MFC提供的这个函数在装载DLL的时候调用InitInstance函数,而在DLL退出的时候调用ExitInstance函数。所需要完成的初始化和终止的工作需要在这两个函数中完成。,13.3 从DLL中导出函数,关于DLL的函数动态链接库中定义有两种函数:导出函数(export funct

8、ion)和内部函数(internal function)。导出函数可以被其它模块调用,内部函数在定义它们的DLL程序内部使用。,13.3.1 使用DEF文件导出函数,模块定义文件(.DEF)是一个或多个用于描述DLL属性的模块语句组成的文本文件,每个DEF文件至少必须包含以下模块定义语句: 第一个语句必须是LIBRARY语句,指出DLL的名字; EXPORTS语句列出被导出函数的名字;将要输出的函数修饰名罗列在EXPORTS之下,这个名字必须与定义函数的名字完全一致,如此就得到一个没有任何修饰的函数名了。 可以使用DESCRIPTION语句描述DLL的用途(此句可选); “;”对一行进行注释(

9、可选)。,13.3.2 使用关键字_declspec(dllexport),使用MFC提供的修饰符号_declspec(DLLexport)在要输出的函数、类、数据的声明前加上_declspec(DLLexport)的修饰符,表示输出。_declspec(DLLexport)在C调用约定、C编译情况下可以去掉输出函数名的下划线前缀。extern “C“使得在C+中使用C编译方式成为可能。在C+下定义C函数,需要加extern “C“关键词。用extern “C“来指明该函数使用C编译方式。输出的C函数可以从C代码里调用。,13.3.3 使用AFX_EXT_CLASS导出,MFC扩展DLL使用A

10、FX_EXT_CLASS来导出类,链接这种DLL的应用程序或其他DLL使用这个宏来导入类。 如果用于DLL应用程序的实现中,则表示输出;如果用于使用DLL的应用程序中,则表示输入。要输出整个的类,对类使用_declspec(_DLLexpot);要输出类的成员函数,则对该函数使用_declspec(_DLLexport)。,13.4 DLL中的数据和内存,13.4.1 DLL多进程间的数据共享,DLL被多个进程调用,它的代码从而被映射到不同的进程内存空间之中,DLL共享数据也尽量只在系统中有一个拷贝,这是通过COPY-ON-WRITE技术实现的。 使用共享数据段,首先需要把欲放入数据段的数据定

11、义在特定的数据段中,然后在说明这个数据段是共享数据段就可以了。,13.4.2 DLL进程中多线程间的数据隔离,Windows API提供了进程中多线程数据分离的一系列TLS(Thread Local Storage)函数,这是进程内线程隔离的解决方法,TLS函数集共有四个函数: DWORD TlsAlloc (VOID); BOOL TlsFree(DWORD dwTlsIndex); LPVOID TlsGetValue (DWORD dwTlsIndex); BOOL TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue); 函数TlsAlloc用来

12、分配线程局部变量索引,它的返回值是后面三个函数的参数dwTlsIndex。而函数TlsFree负责释放线程变量索引。所以这两个函数应该在副线程创建之前的主线程中调用。在DLL模块中,就是在入口点函数被参数调用时候使用。 线程运行过程中,可以使用函数TlsGetValue和TlsSetValue根据线程变量的索引号存取各自的数据指针,并存取到各自的数据。,13.5 几种常用的DLL,MFC中的DLLa、Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC的应用程序所调用。,13.5.1 Win32 DLL,VC6支持自动生成

13、的Win32 DLL和MFC AppWizard DLL,其中自动生成的Win32 DLL共包括三种DLL工程。从FILE|NEW菜单项,选择对话框中的Projects选项卡,图13.1 选中Win32 Dynamic-Link Liabrary,输入工程名,点击OK按钮后,弹出如下对话框图13.2所示:选择所要生成的Win32 DLL类型了。,13.5.2 Regular statically linked to MFC DLL,在VC6中有三种形式的MFC DLL(在该DLL中可以使用和继承已有的MFC类)可供选择,即Regular statically linked to MFC DLL

14、(标准静态链接MFC DLL)和Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。 第一种DLL的特点是,在编译时把使用的MFC代码加入到DLL中,因此,在使用该程序时不需要其他MFC动态链接类库的存在,但占用磁盘空间比较大;,13.5.3 Regular using the shared MFC DLL,第二种DLL的特点是:在运行时,动态链接到MFC类库,因此减少了空间的占用,但是在运行时却依赖于MFC动态链接类库。动态链接到MFC的规则DLL应用程序里头的输出函数可以被任意Win32

15、程序使用,包括使用MFC的应用程序。但是,所有从DLL输出的函数应该以如下语句开始: AFX_MANAGE_STATE(AfxGetStaticModuleState( ) 此语句用来正确地切换MFC模块状态。,13.5.4 MFC Extension DLL,第三种DLL的特点类似于第二种,作为MFC类库的扩展,只能被MFC程序使用。 Extension DLL用来实现从MFC所继承下来的类的重新利用,就是说,用这种类型的动态连接库,可以用来输出一个从MFC所继承下来的类。它输出的函数仅可以被使用MFC且动态链接到MFC的应用程序使用。可以从MFC继承所想要的,更适于用户自己用的类,并把它提

16、供给应用程序。也可随意的给应用程序提供MFC或MFC继承类的对象指针。Extension DLL使用MFC的动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。,13.6 DLL的调用和调试,13.6.1 VC对DLL的调用,系统运行一个调用DLL的程序时,将在以下位置查找 该DLL: 1包含EXE文件的目录 2进程的当前工作目录 3Windows系统目录 4Windows目录 5列在Path环境变量中的一系列目录 若找不到该文件,系统将显示对话框提示并终止程序 的执行,,13.6.2 VB对DLL 的调用,在VB中调用Windows DLL之前,必须在Standard(代码)模块的Declarations段中加一个特殊的声明。对于一个DLL或API函数,Declare语句是Windows所必需的,这一点很重要。并且在32位版的VB中动态链接库中的函数对条件是很敏感的。,13.6.3 DLL的调试,DLL的调试有很多中方法,但都需要把DLL工程生成的后缀名为.dll的文件放在执行它的应用程序可以

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

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

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