Visual C++程序设计教程(第二版)课件:动态链接库_第1页
Visual C++程序设计教程(第二版)课件:动态链接库_第2页
Visual C++程序设计教程(第二版)课件:动态链接库_第3页
Visual C++程序设计教程(第二版)课件:动态链接库_第4页
Visual C++程序设计教程(第二版)课件:动态链接库_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

动态链接库

13.1DLL基础知识本节讲述DLL的基础知识。13.1.1DLL概述 Windows系统平台上提供了一种完全不同的有效的编程和运行环境,可以将独立的程序模块创建为较小的DLL(DynamicLinkableLibrary)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL模块的形式实现。13.1.2认清DLL与LIB DLL与LIB的相似之处是它们都是将一部分可执行代码以及数据放在库中供用户程序使用,而且在使用时,这些代码就象是用户程序本身的一部分。LIB文件是静态链接库文件,在其中放置了许多的函数和变量。其中一部分函数和变量是供内部使用的,在接口中不可见,即没有输出;另一部分是供接口使用的(当然内部函数也可以使用),外部可见,从而应用程序可以调用这些输出的函数和变量。在DLL中同样包括许多变量和函数,也分为内部变量、函数和外部接口函数、变量。对于内部的函数和变量,供DLL自己调用,因此并不包含名称,只使用地址;对于供外部调用的函数和变量,在内部的时候也使用地址,只是在头文件中包含了输出变量和函数的名称,而且包含了这些名称所对应的地址,即将名称和地址对应起来。通过这些名称就可以查找对应变量和函数的地址(函数的地址是指函数入口点的地址)。13.1.3认清DLL与EXEDLL和EXE都是Windows下的可执行模块,在对应的文件结构上,它们也类似的:具有文件头,重定位信息表,导入动态库表等,另外,DLL作为供程序调用的服务者,文件中还包含导出的函数表和变量表。DLL是服务的提供者,主要用来提供输出变量和函数供别的程序调用,在DLL被装入的时候,以及进程中创建线程的时候,Windows都会以不同的参数调用入口点函数,然后该函数进行某些初始化工作后返回,DLL的执行就停止了。Windows并不为DLL创建单独的进程空间,而是将其装入共享地址,然后将其映射到不同的进程供进程调用,从而达到代码共享的目的。EXE是DLL所提供服务的使用者,调用DLL中的输出的函数和变量,每一个EXE在运行的时候,Windows均为它创建单独的进程环境,包括进程地址空间,EXE就在它的地址空间中运行,对别的进程是不透明的,因此也就无法为别的进程调用,因此在许多情况下只能使用DLL来实现某些功能。13.1.4DLL的两种动态链接方法加载时动态链接 由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。运行时动态链接 是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。13.2DLL入/出口函数 Win32DLL与Win16DLL有很大的区别,这主要是由操作系统的设计思想决定的。一方面,在Win16DLL中程序入口点函数和出口点函数(LibMain和WEP)是分别实现的;而在Win32DLL中却由同一函数DLLMain来实现。无论何时,当一个进程或线程载入和卸载DLL时,都要调用该函数。13.2.1DllMain函数

每一个DLL必须有一个入口点,DLLMain是一个缺省的入口函数。DLLMain负责初始化(Initialization)和结束(Termination)工作,每当一个新的进程或者该进程的新的线程访问DLL时,或者访问DLL的每一个进程或者线程不再使用DLL或者结束时,都会调用DLLMain。但是,使用TerminateProcess或TerminateThread结束进程或者线程,不会调用DLLMain。13.2.2MFCAppWizard生成的RegularDLL入/出口 MFCAppWizard生成的RegularDLL在后面的章节会有介绍,这里只讨论它的入/出口点问题。 每个RegularDLL都有MFCAppWizard自动生成的CWinApp派生类的对象,与其它MFC应用程序一样,它是在CWinApp派生类的成员函数InitInstance和ExitInstance完成初始化和终止的工作。 实际上,MFC提供了一个基本的DllMain函数,在这种DLL中不必自己编写DllMain函数,由MFC提供的这个函数在装载DLL的时候调用InitInstance函数,而在DLL退出的时候调用ExitInstance函数。所需要完成的初始化和终止的工作需要在这两个函数中完成。13.3从DLL中导出函数

关于DLL的函数动态链接库中定义有两种函数:导出函数(exportfunction)和内部函数(internalfunction)。导出函数可以被其它模块调用,内部函数在定义它们的DLL程序内部使用。13.3.1使用DEF文件导出函数

模块定义文件(.DEF)是一个或多个用于描述DLL属性的模块语句组成的文本文件,每个DEF文件至少必须包含以下模块定义语句:第一个语句必须是LIBRARY语句,指出DLL的名字;

EXPORTS语句列出被导出函数的名字;将要输出的函数修饰名罗列在EXPORTS之下,这个名字必须与定义函数的名字完全一致,如此就得到一个没有任何修饰的函数名了。可以使用DESCRIPTION语句描述DLL的用途(此句可选);“;”对一行进行注释(可选)。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使用AFX_EXT_CLASS来导出类,链接这种DLL的应用程序或其他DLL使用这个宏来导入类。 如果用于DLL应用程序的实现中,则表示输出;如果用于使用DLL的应用程序中,则表示输入。要输出整个的类,对类使用_declspec(_DLLexpot);要输出类的成员函数,则对该函数使用_declspec(_DLLexport)。13.4DLL中的数据和内存13.4.1DLL多进程间的数据共享 DLL被多个进程调用,它的代码从而被映射到不同的进程内存空间之中,DLL共享数据也尽量只在系统中有一个拷贝,这是通过COPY-ON-WRITE技术实现的。 使用共享数据段,首先需要把欲放入数据段的数据定义在特定的数据段中,然后在说明这个数据段是共享数据段就可以了。13.4.2DLL进程中多线程间的数据隔离 WindowsAPI提供了进程中多线程数据分离的一系列TLS(ThreadLocalStorage)函数,这是进程内线程隔离的解决方法,TLS函数集共有四个函数:DWORDTlsAlloc(VOID);BOOLTlsFree(DWORDdwTlsIndex);LPVOIDTlsGetValue(DWORDdwTlsIndex);BOOLTlsSetValue(DWORDdwTlsIndex,LPVOIDlpTlsValue);

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

选中Win32Dynamic-LinkLiabrary,输入工程名,点击OK按钮后,弹出如下对话框图13.2所示:选择所要生成的Win32DLL类型了。13.5.2RegularstaticallylinkedtoMFCDLL

在VC6中有三种形式的MFCDLL(在该DLL中可以使用和继承已有的MFC类)可供选择,即RegularstaticallylinkedtoMFCDLL(标准静态链接MFCDLL)和RegularusingthesharedMFCDLL(标准动态链接MFCDLL)以及ExtensionMFCDLL(扩展MFCDLL)。 第一种DLL的特点是,在编译时把使用的MFC代码加入到DLL中,因此,在使用该程序时不需要其他MFC动态链接类库的存在,但占用磁盘空间比较大;13.5.3RegularusingthesharedMFCDLL

第二种DLL的特点是:在运行时,动态链接到MFC类库,因此减少了空间的占用,但是在运行时却依赖于MFC动态链接类库。动态链接到MFC的规则DLL应用程序里头的输出函数可以被任意Win32程序使用,包括使用MFC的应用程序。但是,所有从DLL输出的函数应该以如下语句开始:AFX_MANAGE_STATE(AfxGetStaticModuleState())此语句用来正确地切换MFC模块状态。13.5.4MFCExtensionDLL

第三种DLL的特点类似于第二种,作为MFC类库的扩展,只能被MFC程序使用。

ExtensionDLL用来实现从MFC所继承下来的类的重新利用,就是说,用这种类型的动态连接库,可以用来输出一个从MFC所继承下来的类。它输出的函数仅可以被使用MFC且动态链接到MFC的应用程序使用。可以从MFC继承所想要的,更适于用户自己用的类,并把它提供给应用程序。也可随意的给应用程序提供MFC或MFC继承类的对象指针。ExtensionDLL使用MFC的动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。13.6DLL的调用和调试13.6.1VC对DLL的调用

系统运行一个调用DLL的程序时,将在以下位置查找该DLL:1.包含EXE文件的目录2.进程的当前工作目录3.Windows系统目录4.Windows目录5.列在Path环境变量中的一系列目录 若找不到该文件,系统将显示对话框提示并终止程序的执行,13.6.2VB对DLL的调用

在VB中调用WindowsDLL之前,必须在Standard(代码)模块的Declarations段中加一个特殊的声明。对于一个DLL或API函数,Declare语句是Windows所必需的,这一点很重要。并且在32位版的VB中动态链接库中的函数对条件是很敏感的。13.6.3DLL的调试 DLL的调试有很多中方法,但都需要把DLL工程生成的后缀名为.dll的文件放在执行它的应用程序可以找到的目录中。这可以有很多中方法,手工也行的。 应用VC可以很容易地调试DLL,只要从DLL工程中运行调试程序即可。当第一次调试DLL的时候,调试程序会跳出如下对话框图13.5。13.7DLL例程13.7.1使用已有的DLL

本例程将通过调用DLL来实现程序的隐藏,即不显示程序窗口,程序不显示在任务栏上,在按下Ctrl+Alt+Del键后出现的任务列表中也不显示。 首先创建工程:1.在VC++集成开发环境中,通过菜单File|New,弹出New对话框;2.在Projects选项卡中选择MFCAppWizard(exe),在Projectname中输入“Eg13_1”Location读者可以自己选择;3.按下OK按钮,在弹出的MFCAppWizardStep-1对话框中选择程序框架为单文档框架,即选中SingleDocument;4.按下OK按钮,在弹出的NewProjectInformation对话框中按下OK按钮后等待创建完相应的工程。参考课本260页13.7.2资源DLL本例程将建立两个DLL文件以实现自己的双语菜单。首先创建工程Eg13_2:1.在VC++集成开发环境中,通过菜单File|New,弹出New对话框;2.在Projects选项卡中选择MFCAppWizard(exe),在Projectname中输入“Eg13_2”Location读者可以自己选择;3.按下OK按钮,在弹出的MFCAppWizardStep-1对话框中选择程序框架为单文档框架,即选中SingleDocument;4.按下Finish按钮,在弹出的NewProjectInformation对话框中按

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论