动态链接库[new]

上传人:suns****4568 文档编号:93222162 上传时间:2019-07-18 格式:PPT 页数:18 大小:1.68MB
返回 下载 相关 举报
动态链接库[new]_第1页
第1页 / 共18页
动态链接库[new]_第2页
第2页 / 共18页
动态链接库[new]_第3页
第3页 / 共18页
动态链接库[new]_第4页
第4页 / 共18页
动态链接库[new]_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《动态链接库[new]》由会员分享,可在线阅读,更多相关《动态链接库[new](18页珍藏版)》请在金锄头文库上搜索。

1、动态链接库,目 录,01,静态链接库,概论,先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库静态链接库动态链接库”的时代。静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或

2、者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。,静态链接库,静态链接库就是你使用的.lib文件,库中得代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。 引用: 一、通用: 格式如:#pragma comment(lib,“XXX.lib“) 二、针对开发环境: 1、如果使用VC,可以在Project Setting-Link中加入你的静态库,也可以直接把该.lib文件加入到你的工程中 2、如果使用Visual Studio,位置在 项目配置属性连接器输入附加依赖项 中加入.lib文件 在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*

3、.LIB),Visual C+的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为“静态链接“,此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。,静态链接库总结,静态链接的最大缺点是生成的可执行文件太大,需要独占更多的系统资源,在装入内存时也会消耗更多的时间。 (1)库不是个怪物,编写库的程序和编写一般的程序区别不大,只是库不能单独执行; (2)库提供一些可以给别的程序调用的东西,别的程序要调用它必须以某种方式指明它要调用之。 以上从静态链接库分析而得到的对库的初级概念可以直接引申

4、到动态链接库中,动态链接库与静态链接库在编写和调用上的不同体现在库的外部接口定义及调用方式略有差异。,动态链接库,动态链接库(Dynamic-Link Library),简称DLL。它是基于Windows程序设计的一个非常重要的组成部分。自从微软推出第一个版本的Windows操作系统以来,动态链接库(DLL)一直是Windows操作系统的基础。 在建立应用程序的可执行文件时,不必将DLL链接到程序中,而是在运行时动态装载DLL,装载时DLL被映射到进程的地址空间中。 动态链接库通常都不能直接运行。 DLL是一种基于Windows的程序模块,它不仅可以包含可执行代码,还能有数据,各种资源,扩大了

5、库文件的使用范围。比如:Windows API中的所有函数都包含在DLL中。我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。 一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。由此可见DLL对我们来说其实并不陌生。,静态库和动态库,函数和数据被编译进一个二进制文件(

6、通常扩展名为.LIB)。 静态库:在使用静态库的情况下,在编译链接可执行文件时,链接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件(.EXE文件)。在多个同样的程序执行时,系统保留了许多重复的代码副本,造成内存资源浪费。 在使用动态库的时候,往往提供两个文件:一个引入库和一个DLL。引入库包含被DLL导出的函数和变量的符号名,DLL包含实际的函数和数据。在编译链接可执行文件时,只需要链接引入库,DLL中的函数代码和数据并不复制到可执行文件中,在运行的时候,再去加载DLL,访问DLL中导出的函数。使用DLL的动态链接并不是将库代码拷贝,只是在程序中记录了函数的

7、入口点和接口,在程序执行时才将库代码装入内存;不管多少程序使用DLL,内存中都只有一个DLL的副本;当没有程序使用它时,系统就将它移出内存,减少了对内存和磁盘的要求。 静态库中不能再包含其他的动态或静态库,而动态库则可以。,使用动态链接库的好处,DLL技术对于开发大型软件系统:一个大型系统要是用一个执行文件完成,程序将太庞大了,而且可能有许多重复的功能。这时将程序分成一个主程序和一系列的DLL,可以减少开发的工作量。由于每个模块减小了,访问的速度将提高。 开发者可以将依赖于语言的函数和资源分离出来,专门放进DLL中,例如中文、英文、法文等。各地使用软件的用户可以安装或者运行适当的DLL,以获取

8、正确的本地信息,这是实现软件商品国际化的一项技术。 可以采用多种编程语言来编写。 增强产品的功能。 提供二次开发的平台。 简化项目管理。 可以节省磁盘空间和内存。 有助于资源的共享。 有助于实现应用程序的本地化。,动态链接库被多个进程访问,代码页面2,代码页面1,数据页面2,代码页面3,数据页面1,DLL的虚拟内存,代码页面2,代码页面1,数据页面2,代码页面3,数据页面1,代码页面1,代码页面2,代码页面3,数据页面1,数据页面2,代码页面2,代码页面2,代码页面3,数据页面1,数据页面2,代码页面1,第一个进程的地址空间,第二个进程的地址空间,隐式链接(隐式加载) 显示链接(动态加载),动

9、态链接库加载 的两种方式,隐式链接,隐式链接的特点是由编译器完成对DLL的加载和程序结束时对DLL的卸载工作,如果程序结束时如果还有其他应用程序使用该DLL,那么系统会使DLL的使用计数减1,当DLL的使用计数降为0时,会将DLL从内存中删除 优缺点:隐式链接DLL的方法简单实用,但缺少灵活性。 使用方法:使用隐式链接DLL开发时,首先,需要将DLL的引入库文件(*.lib-编译生成DLL时,会一起生成的)与应用程序进行静态链接,因为引入库文件包含DLL的各种输出资源,如导出函数,导出类等信息,这些信息指向DLL的函数指针等等,EXE执行时,DLL被 “自动” 加载,EXE退出时DLL被 “自

10、动” 卸载。,显示链接,显示链接方式是完全由编程者用API 加载和卸载DLL,编程者可以决定何时加载DLL,加载哪个DLL,何时卸载DLL,卸载哪个DLL等。 优缺点:显示链接方式充分体现了DLL的灵活性,是比较常用的调用DLL方式。但是与静态链接相比稍微复杂了些。 使用方法: LoadLibrary(.):该 API 用于加载指定的DLL; GetProcAddress(.):该 API 用于获取DLL中导出函数的指针, 即导出函数的入口点; FreeLibrary(.):该 API 用于卸载指定的DLL。 注:如果程序中多次调用LoadLibrary(.)加载同一DLL时,在卸载的时候也要

11、调用相应次数的FreeLibrary(.)进行卸载。,显示连接,使用LoadLibrary显式链接,在这个函数的参数中可以指定DLL文件的完整路径。如果不指定路径,Windows将遵循如下的搜索顺序来定位DLL: EXE文件所在的目录: 进程的当前工作目录: Windows系统目录:例如:C:WINDOWSsystem32 Windows目录:例如:C:WINDOWS 环境变量的目录:我的电脑属性高级环境变量 说明: 进程的当前工作目录:使用函数SetCurrentDirectory(.)设置的路径,或者从父进程继承而来的路径,使用GetCurrentDirectory(.)得到。 EXE文件

12、所在的目录:本EXE文件所在的绝对路径, 使用GetModuleFileName得到。 两者可能不同。 GetProcAddress函数可以有两种方式取得DLL导出函数的入口点: 例如: GetProcAddress(hMod, “add“); /按照函数名称方式; GetProcAddress(hMod, MAKEINTRESOURCEA(1); /按照导出函数序号方式;,DLL程序入口点函数,BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) return TRUE; hM

13、odule参数:指向DLL本身的实例句柄; ul_reason_for_call参数:指明了DLL被调用的原因,可以有以下4个取值: DLL_PROCESS_ATTACH: 当DLL被进程 调用时,导致DllMain函数被调用,同时 ul_reason_for_call的值为DLL_PROCESS_ATTACH,如果同一个进程后来再 次调用此DLL时,操作系统只会增加DLL的使用次数,不会再用 DLL_PROCESS_ATTACH调用DLL的DllMain函数。 DLL_PROCESS_DETACH: 当DLL被从进程的地址空间解除映射时,系统调用了它的DllMain,传递的 ul_reaso

14、n_for_call值是DLL_PROCESS_DETACH。 如果进程的终结是因为调用了TerminateProcess,系统就不会用 DLL_PROCESS_DETACH来调用DLL的DllMain函数。这就意味着DLL在进程 结束前没有机会执行任何清理工作。,DLL程序入口点函数,DLL_THREAD_ATTACH: 当进程创建一线程时,系统查看当前映射到进程地址空间中的所有DLL文件映像,并用值DLL_THREAD_ATTACH调用DLL的DllMain函数。 新创建的线程负责执行这次的DLL的DllMain函数,只有当所有的DLL都处理完这一通知后,系统才允许线程开始执行它的线程函数

15、。 DLL_THREAD_DETACH: 如果线程调用了ExitThread来结束线程(线程函数返回时,系统也会自动调用ExitThread),系统查看当前映射到进程空间中的所有DLL文件映像,并用DLL_THREAD_DETACH来调用DllMain函数,通知所有的DLL去执行线程级的清理工作。 注意:如果线程的结束是因为系统中的一个线程调用了TerminateThread,系统就不会用值DLL_THREAD_DETACH来调用所有DLL的DllMain函数 lpReserved参数:保留,目前没什么意义。,动态链接库的分类,动态链接库的分类,非MFC的DLL - 即使用 SDK API 进

16、行编程,能被其他所有语言调用; MFC规则DLL - 可以使用 MFC 进行编程,能被其他所有语言调用; MFC扩展DLL - 可以使用 MFC进行编程,但只能被用MFC编写的程序调用。,附:extern “C“ 包含双重含义,(1) 被extern “C“限定的函数或变量是extern类型的 extern是C/C+语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。 通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在链接阶段中从模块A编译生成的目标代码中找到此函数。 与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可

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

当前位置:首页 > 大杂烩/其它

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