




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、库文件1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库静态链接库动态链接库”的时代。静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还
2、可以再包含其他的动态或静态链接库。对动态链接库,我们还需建立如下概念:(1)DLL 的编制与具体的编程语言及编译器无关只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C+还是Delphi。(2)动态链接库随处可见我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数
3、主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。由此可见DLL对我们来说其实并不陌生。(3)VC动态链接库的分类Visual C+支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DL
4、L 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。2.静态链接库对静态链接库的讲解不是本文的重点,但是在具体讲解DLL之前,通过一个静态链接库的例子可以快速地帮助我们建立“库”的概念。 用visual studio 创建动态库如图1,在VC+6.0中new一个名称为libTest的static library工程(单击此处下载本工程),并新建lib.h和lib.cpp两个文件,lib.h和lib.cpp的源代码如下:/文件:lib.h#ifndef LIB_H#define LIB_Hextern &
5、quot;C" int add(int x,int y);/声明为C编译、连接方式的外部函数#endif/文件:lib.cpp#include "lib.h"int add(int x,int y)return x + y;编译这个工程就得到了一个.lib文件,这个文件就是一个函数库,它提供了add的功能。将头文件和.lib文件提交给用户后,用户就可以直接使用其中的add函数了。标准Turbo C2.0中的C库函数(我们用来的scanf、printf、memcpy、strcpy等)就来自这种静态库。下面来看看怎么使用这个库,在libTest工程所在的工作区内new
6、一个libCall工程。libCall工程仅包含一个main.cpp文件,它演示了静态链接库的调用方法,其源代码如下:#include <stdio.h>#include ".lib.h"#pragma comment( lib, ".debuglibTest.lib" ) /指定与静态库一起连接int main(int argc, char* argv)printf( "2 + 3 = %d", add( 2, 3 ) );静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明白这个概念。代码中#pragma
7、comment( lib , ".debuglibTest.lib" )的意思是指本文件生成的.obj文件应与libTest.lib一起连接。如果不用#pragma comment指定,则可以直接在VC+中设置,如图2,依次选择tools、options、directories、library files菜单或选项,填入库文件路径。图2中加红圈的部分为我们添加的libTest.lib文件的路径。 在VC中设置库文件路径这个静态链接库的例子至少让我们明白了库函数是怎么回事,它们是哪来的。我们现在有下列模糊认识了:(1)库不是个怪物,编写库的程序和编写一般的程序区别不大,只是库
8、不能单独执行;(2)库提供一些可以给别的程序调用的东东,别的程序要调用它必须以某种方式指明它要调用之。以上从静态链接库分析而得到的对库的懵懂概念可以直接引申到动态链接库中,动态链接库与静态链接库在编写和调用上的不同体现在库的外部接口定义及调用方式略有差异。 静态库目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。 静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静
9、态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。 动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。 导入库和静态库的区别导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。 这也是实际上很多开源代码发布的惯用方式: 1. 预
10、编译的开发包:包含一些.dll文件和一些.lib文件。其中这里的.lib就是导入库,而不要错以为是静态库。但是引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。而.dll则最好放到最后产生的应用程序exe执行文件相同的目录。这样运行时,就会自动调入动态链接库。 2. 用户自己编译: 下载的是源代码,按照readme自己编译。生成很可能也是.dll + .lib(导入库)的库文件 3. 如果你只有dll,并且你知道dll中函数的函数原型,那么你可以直接在自己程序中使用LoadLibary调入DLL文件,然后使用GetProcAddress调用DLL中的函数。当DLL被链接时,链接程
11、序要查找关于输出变量,函数,或C+类的信息,并自动生成一个lib文件。该lib文件包含一个DLL输出的符号列表。如果要链接引用该DLL的输出符号的任何可执行模块,该lib文件是必不可少的(使用GetProcAddress除外)。其实导入库中并不含RVA(每个符号的相对虚拟地址),只是一些符号而已,还有关于这个lib所对应的DLL的名字等。 (这只是我现在的理解)那当应用程序调用一个DLL的函数时,是怎么进行的呢?(使用lib的情况下)答案是在进程的主线程开始运行之前,由加载器完成。加载器根据输入节中DLL的名字按照windows的搜索路径搜索DLL,找到后DLL映射到进程的地址空间,这是DLL
12、中对应于输入节中的各个符号的地址就可以确定了,加载器在这个时候将地址重新填入可执行模块的输入节中,动态连接完成。DEF文件的写法:LIBRARY BTREE / 库名为BTREE,省略库名即为动态链接库文件名EXPORTS / 输出 Insert 1 / 带序号的输出函数名 Delete 2 Member
13、160; 3 Min 4Dynamic-Link Libraries概述Microsoft Windows DLL程序是包函数和数据的模块。由调用它的其它模块(EXE或DLL)动态加载。加载时,它被映像到调用模块的地址空间内。DLL可以定义两类函数:输出函数和内部函数。输出函数可以被其它模块调用。可以定义输出数据,但输出数据一般只由它自己的函数使用。DLL有助于应用程序实现模块化。当多个应用程序使用相同的模块时,还能减少内存占用,原因是每个应用程序会有自己的数据复本,DLL的代码是共享的。动态链接允许模块只包含装载时或运行时系统需要的
14、信息,这点与静态链接不同。静态链接时系统会为每个调用模块拷贝一份相应的函数代码。每个被装载的DLL都由系统设置一个计数标志。某个线程使用DLL时,系统将这个计数值加1,线程结束时,计数值减1。当计数值减到0时,系统将其从调用模块的虚拟空间中卸载。使用DLL需要有如下规定:1.装载DLL的线程可以使用该DLL打开的句柄。同样,调用模块的线程打开的其它句柄也可以由DLL使用。2.DLL使用调用线程的堆栈。3.DLL参考调用进程的虚拟内存定位地址。动态链接形式使用DLL有两种方法:1.启动装载动态链接。模块直接调用DLL输出函数。调用模块事先必须用输入函数表连接到DLL及其使用的其它DLL或库。模块
15、的输入函数表会指导操作系统,在应用程序装载时需要的DLL函数的信息和定位方式。2.运行装载动态链接。调用模块用LoadLibrary或LoadLibraryEx函数在运行时刻装载DLL。调用模块用GetProcAddress函数等到DLL函数的句柄,用这个句柄调用其函数。这种方法不用输入函数表。动态链接的优点相比静态链接,动态链接有几个优点:1.多个进程在同一基地址装载相同DLL,只需要一个共享DLL即可,它在物理地址空间内共享。2.DLL内的函数变化,只要其输入输入参数、调用格式没有变,应用程序自身不必重新编译。静态链接需要重新编译。3.DLL提供异步支持。比如应用程序装载DLL时,用DLL
16、支持一个无效设备。4.不同语言编写的应用程序可以用约定的调用格式调用DLL函数。潜在缺点是应用程序不是相对独立的。启动装载动态链接时,DLL不存在,程序不被装载。运行装载时,如果DLL不存在,由程序处理。创建动态链接库创建DLL需要一个或多个源文件,可能需要输出函数用的连接文件。如果是启动装载的DLL,还要创建输入库。源文件内是输出函数和内部函数,可选的DLL入口函数。DLL由多线程的应用程序使用,要将DLL连接成thread-safe类型,以支持多线程,也要同步全局数据。输出函数的定义是需要编译程序支持的,声明方式也不相同。使用MS VC+,有两种定义输出函数的方式:源文件中使用_decls
17、pec 定义,或用.DEF文件定义。输入库(.LIB)文件包含连接程序需要的DLL输出函数,系统定位指定的DLL及其输出函数。VC+中要指定该DLL的输入库文件(.LIB),才能编译使用该DLL中的函数。DLL入口函数每个DLL必须有入口点,并不必须有入口函数,入口点由连接程序指定。应用程序装载或卸载DLL时系统会调用入口函数。一般在这里进行初始化工作。参看DllEntryPoint函数,用户可以更改这个函数名,也要参看连接程序文档。调用入口程序的事件:1.装载DLL后。2.卸载DLL之前。3.进程创建了一个新线程。使用DisableThreadLibraryCalls函数会取消这个动作。4.
18、线程正常结束,不是使用TerminateThread或TerminateProcess函数。同一时刻只有一个线程允许调用DLL入口函数。DLL可以使用TLS(线程局部存贮表)获得线程信息。定义格式:BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL, / handle to DLL module DWORD fdwReason, / reason for calling function
19、LPVOID lpReserved ) / reserved函数开头处,可以获得系统传递的调用信息:A process loads the DLL (DLL_PROCESS_ATTACH). The current process creates a new thread (DLL_THREAD_ATTACH). A thread exits normally (DLL_THREAD_DETACH). A process unloads the DLL (DLL_PROCESS_DETACH)不定义入口函数,装载时会产生错误。入口函数操作成功应该返回TRUE。启动装载DLL时的搜索路径1.启动模块路径。2.当前路径。3.Windows系统路径。GetSystemDirectory函数可以返回这个路径。4.Windows路径。GetWindowsDirectory函数返回这个路径。5.PATH环境路径。运行装载DLL不同路径的重名DLL不会认为是相同的DLL。 LoadLibrary 或 LoadLibraryEx函数会调用DLL入口函数。 GetModuleHandle 函数返回DLL句柄。GetProcAddress函数获得地址。运行时加载DLL,在DLL出错时,应用程序仍可运行,但不能再使用该DLL中的函数。DLL的数据DLL缺省的变量使用范围与
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年合同制合同工基本信息登记表
- 中介不退定金合同标准文本
- 1000消防设计合同标准文本
- 作品集合同标准文本
- 疫情防控课件题目中班
- 二灰分包合同标准文本
- 个人服务合同标准文本英文
- 个体注册合同标准文本
- 党建共享共建合同标准文本
- 买卖租凭合同标准文本
- GB/T 8545-2012铝及铝合金模锻件的尺寸偏差及加工余量
- GB/T 6730.65-2009铁矿石全铁含量的测定三氯化钛还原重铬酸钾滴定法(常规方法)
- 威尼斯的小艇 省一等奖
- 企业人力资源管理师(四级)教材
- 教科版六年级下册科学第一单元测试卷(原卷版)
- 【教学课件】正确行使诉讼权利-示范课件
- 促进市级医院临床技能与临床创新三年行动计划
- 主观幸福感(GWB)量表
- 临床试验疑难问题解答
- Word版中国空白地图大全
- 玻璃纤维生产工艺流程培训
评论
0/150
提交评论