动态链接库和静态链接库.ppt_第1页
动态链接库和静态链接库.ppt_第2页
动态链接库和静态链接库.ppt_第3页
动态链接库和静态链接库.ppt_第4页
动态链接库和静态链接库.ppt_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

静态链接库和动态链接库 测绘学院 李新维邮箱 xinweil 目录 概念定义 1 静态链接库的创建 动态链接库的创建 应用实例 1 概念定义 1 1分别编译与链接 大多数高级语言都支持分别编译 compling 程序员可以显式地把程序划分为独立的模块或文件 然后由编译器 compiler 对每个独立部分分别进行编译 在编译之后 由链接器 Linker 把这些独立编译单元链接 Linking 到一起 链接方式有两种 静态链接 动态链接 1 2链接方式 静态链接方式 在程序开发中 将各种目标模块 OBJ 文件 运行时库 LIB 文件 以及已编译的资源 RES 文件链接在一起 以便创建Windows的 EXE文件 动态链接方式 在程序运行时 Windows把一个模块中的函数调用链接到库模块中的实际函数上的过程 1 2链接方式 静态链接库 简称LIB 与动态链接库 简称DLL 都是共享代码的方式 如果使用静态链接库 也称静态库 则无论你愿不愿意 LIB文件中的指令都会被直接包含到最终生成的 EXE文件中 但是若使用 DLL文件 该 DLL文件中的代码不必被包含在最终的 EXE文件中 EXE文件执行时可以 动态 地载入和卸载这个与 EXE文件独立的 DLL文件 1 3动态链接方式 链接一个DLL有两种方式 1 载入时动态链接 Load TimeDynamicLinking 2 运行时动态链接 Run TimeDynamicLinking 1 3 1载入时动态链接 使用载入时动态链接 调用模块可以像调用本模块中的函数一样直接使用导出函数名调用DLL中的函数 这需要在链接时将函数所在DLL的导入库链接到可执行文件中 导入库向系统提供了载入DLL时所需的信息及用于定位DLL函数的地址符号 相当于注册 当作API函数来使用 其实API函数就存放在系统DLL当中 1 3 2运行时动态链接 使用运行时动态链接 运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL DLL载入后 模块可以通过调用GetProcAddress获取DLL函数的入口地址 然后就可以通过返回的函数指针调用DLL中的函数了 如此即可避免导入库文件了 1 4二者优点及不足 静态链接库的优点 1 代码装载速度快 执行速度略比动态链接库快 2 只需保证在开发者的计算机中有正确的 LIB文件 在以二进制形式发布程序时不需考虑在用户的计算机上 LIB文件是否存在及版本问题 可避免DLL地狱等问题 1 4二者优点及不足 动态链接库的优点 1 更加节省内存并减少页面交换 2 DLL文件与EXE文件独立 只要输出接口不变 即名称 参数 返回值类型和调用约定不变 更换DLL文件不会对EXE文件造成任何影响 因而极大地提高了可维护性和可扩展性 3 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数 1 4二者优点及不足 不足之处 1 使用静态链接生成的可执行文件体积较大 包含相同的公共代码 造成浪费 2 使用动态链接库的应用程序不是自完备的 它依赖的DLL模块也要存在 如果使用载入时动态链接 程序启动时发现DLL不存在 系统将终止程序并给出错误信息 而使用运行时动态链接 系统不会终止 但由于DLL中的导出函数不可用 程序会加载失败 3 使用动态链接库可能造成DLL地狱 1 4 1DLL地狱 DLL地狱 DLLHell 是指因为系统文件被覆盖而让整个系统像是掉进了地狱 简单地讲 DLL地狱是指当多个应用程序试图共享一个公用组件时 如某个DLL或某个组件对象模型 COM 类 所引发的一系列问题 1 4 1DLL地狱 最典型的情况是 某个应用程序将要安装一个新版本的共享组件 而该组件与机器上的现有版本不向后兼容 虽然刚安装的应用程序运行正常 但原来依赖前一版本共享组件的应用程序也许已无法再工作 在某些情况下 问题的起因更加难以预料 比如 当用户浏览某些web站点时会同时下载某个MicrosoftActiveX控件 如果下载该控件 它将替换机器上原有的任何版本的控件 如果机器上的某个应用程序恰好使用该控件 则很可能也会停止工作 在许多情况下 用户需要很长时间才会发现应用程序已停止工作 结果往往很难记起是何时的机器变化影响到了该应用程序 2 静态链接库的创建 2 1静态链接库的创建 在此通过一个实例来介绍静态库的创建与使用 在该实例中 我们实现将一个两整数相加求和的函数封装到静态库中供其他程序调用 2 1 1创建一个Win32控制台应用程序 2 1 2选择静态库应用程序类型 2 1 3新建一个 h文件 需要给该静态链接库编写一个声明头文件Static h 以便在链接时告知编译该链接库中的导出函数声明 Static h文件中的内容 ifndef STATIC H define STATIC H 防止该头文件重复引用externintAdd inta intb 声明导出函数 endif 2 1 4新建一个 cpp文件 添加一个用于定义导出函数的源文件Static cpp 编码实现两个整数相加的Add函数 源文件代码如下 include static h intAdd inta intb returna b 2 1 5生成 点击菜单命令 工具 生成Static 如果一切顺利的话 就会在解决方案的 Debug 目录中生成了名为 Static lib 的静态链接库 2 2静态链接库的使用 新建一个Win32控制台应用程序空项目UseLIB 程序主文件名为UseLIB cpp 其中包含用于调用Add函数的程序入口函数main 将刚才创建的Static lib及其声明头文件Static h一同复制到UseLIB项目目录下 并在源文件UseLIB cpp中使用预编译命令链接Static lib 也可以在IDE的项目属性中设置链接器选项 或者只复制Static h文件并设置UseLIB项目的 项目依赖项 为Static项目 2 2静态链接库的使用 源文件UseLIB cpp中的代码如下 pragmacomment lib Static lib 链接静态库Static lib include include Static h 包含Static lib的声明头文件 声明导出函数Addintmain inta 1 b 2 cout a b Add a b 调用Static lib中的Add函数return0 2 2静态链接库的使用 接下来点击菜单命令 工具 生成UseLIB 如果顺利的话 就会在Library解决方案的Debug目录中生成了名为UseLIB exe的可执行执文件 运行UseLIB exe 将在控制台中输出结果 1 2 3 2 3注意 由于项目中创建的源文件为 CPP文件 即C 源文件 因此VisualC 按C 规范 并采用 cdecl调用约定对其进行编译 这样得到的导出函数就不能被C语言程序所调用 解决该问题的办法是在函数体名称前添加extern C 修饰 告诉编译器 该函数按照C语言规范 并采用 cdecl调用约定进行编译 因此源文件Add cpp中的代码可修改如下 extern C intadd inta intb 最后重新编译该静态链接库项目 导出函数Add就能够被C语言程序所调用了 3 动态链接库的创建 3 1动态链接库的创建 在此同样通过一个实例来介绍动态链接库的创建与使用 在实例中 依然使用Add函数进行讲解 这样一方面可以沿用上面静态链接的有关内容 另一方面也可以了解动态链接库与静态链接库在创建和使用上的异同 3 1 1创建一个Win32控制台应用程序 3 1 2选择静态库应用程序类型 3 1 3新建一个 h文件 编写一个声明头文件Dynamic h 以便在以后链接时告知编译器该链接库中的具体的导入内容 一般包括代码和资源 Dynamic h ifndef DYNAMIC H 防止该头文件重复引用 define DYNAMIC H extern C declspec dllexport intAdd inta intb 声明导出函数 endif 3 1 4新建一个 cpp文件 用于定义导出函数的源文件Dynamic cpp 编码实现两个整数相加的Add函数 extern C declspec dllexport intAdd inta intb 声明为DLL导出函数 returna b 3 1 4生成 点工具栏上的生成按钮 则可以在debug下生成 2 2动态链接库的使用 1 载入时动态链接2 运行时动态链接 2 2 1载入时动态链接 将导入库Dynamic lib及其声明头文件Dynamic h一同复制到UseDLL项目目录下 并把Dynamic dll复制到项目的Debug目录中 并在源文件UseDLL cpp中使用预编译命令链接Dynamic lib 也可以在IDE的项目属性中设置链接器选项 源文件UseDLL cpp中的代码如下 pragmacomment lib Dynamic lib 链接导入库Dynamic lib include include Dynamic h 声明头文件 提供导出函数Add的声明intmain inta 1 b 2 cout a b Add a b 调用Dynamic DLL中的Add函数return0 2 2 1运行时动态链接 运行时动态链接的代码相对麻烦些 需要使用到Windows的三个API函数 还要进行一些判断以防止不必要的麻烦 我们在UseDLL项目的基础上做些修改来实现运行时动态链接 这里只需要把Dynamic dll复制到UseDLL项目的Debug目录中 因为不用在编译的时候链接导入库 只要在运行根据需要链接Dynamic dll 2 2 1运行时动态链接 下面先给出修改后的源文件Dynamic cpp的代码 include 用于声明windowAPI函数及宏等 includetypedefint FuncAdd inta intb 定义将要调用的导出函数Add的指针类型intmain FuncAddAdd 定义Add函数指针inta 1 b 2 HMODULEhDLL LoadLibrary TEXT MyDLL dll 载入DLL 并获取其句柄 if hDLL MyDLL dll载入成功 Add FuncAdd GetProcAddress hDLL Add 获取导出函数Add指针if Add 正确获取Add函数指针 cout a b Add a b 调用导出函数Add else 没有找到Add函数 cout AddNotFound n else MyDLL dll载入失败cout LoadLibraryFailed n FreeLibrary TEXT MyDLL dll 释放DLLreturn0 2 2 1运行时动态链接 由于没有链接导入库 不能使用地址符号定位导出函数的入口地址 只能通过GetProcAdress来获取其在地址空间中的指针 再通过指针调用 但程序在运行之前 GetProcAdress无法判断指针的有效性 因此 为了防止Dynamic项目中不存在Add函数而使程序在运行时出错 有必要在调用Add之前判断其函数指针的有效性 4 应用 动态链接库的应用举例 1 所有的Windows系统调用 WindowsAPI函数 都是以动态链接库的形式提供的 我们在Windows目录下的system32文件夹中会看到kernel32 dll user32 dll和gdi32 dll windows的大多数API都包含在这些DLL中 kernel32 dll中的函数主要处理内存管理和进程调度 user32 dll中的函数主要控制用户界面 gdi32 dll中的函数则负责图形方面的操作 与这些动态库相对应的导入库分别为kernel32 lib user32 lib和gdi32 lib 2 软件插件技术 许多Windows应用软件都支持插件扩展方式 如I

温馨提示

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

评论

0/150

提交评论