通信网络程序设计(王晓东西电版)第9章链接库技术

上传人:tian****1990 文档编号:82518444 上传时间:2019-02-24 格式:PPT 页数:90 大小:600.50KB
返回 下载 相关 举报
通信网络程序设计(王晓东西电版)第9章链接库技术_第1页
第1页 / 共90页
通信网络程序设计(王晓东西电版)第9章链接库技术_第2页
第2页 / 共90页
通信网络程序设计(王晓东西电版)第9章链接库技术_第3页
第3页 / 共90页
通信网络程序设计(王晓东西电版)第9章链接库技术_第4页
第4页 / 共90页
通信网络程序设计(王晓东西电版)第9章链接库技术_第5页
第5页 / 共90页
点击查看更多>>
资源描述

《通信网络程序设计(王晓东西电版)第9章链接库技术》由会员分享,可在线阅读,更多相关《通信网络程序设计(王晓东西电版)第9章链接库技术(90页珍藏版)》请在金锄头文库上搜索。

1、,第9章 链 接 库 技 术,9.1 链接库概述 9.2 静态链接库 9.3 动态链接库 9.4 传输服务提供者 小结,在程序设计过程中,往往需要重复使用一段或若干代码(函数或过程),这种需求叫做程序复用。程序复用采用的方法往往是将复用的代码集成为一个个方便调用的包,这种包可以是链接库、类库、COM包、插件、控件,等等。从本章开始,将先后介绍两种代码复用的集成技术,即链接库技术和MFC类库(见第10章)。本章介绍的链接库技术是一种非常有用的代码集成技术,对于代码的复用、软件的升级、调用的标准化、不同编程器的协同编程等都至关重要。,本章首先介绍链接库的概念,然后依次介绍静态和动态两种链接库的概念

2、、调用以及编写方法,继而针对网络中不同类型的动态链接库的调用,介绍了基于链接库技术的Winsock传输服务提供者(Service Provider Interface,SPI)编程。SPI编程为用户设计自己的通信协议、防火墙和木马程序提供了有效手段。,链接库是从C语言函数库和Pascal库单元的概念发展而来的。所有的C语言标准库函数都存放在某一函数库中,同时用户也可以用专用的程序创建自己的函数库。在库函数链接应用程序的过程中,链接器从库文件中拷贝程序调用的函数代码,并把这些函数代码添加到可执行文件中。,9.1 链 接 库 概 述,目前链接库有静态和动态之分,二者的链接方法有所不同。如果采用静态

3、链接库,则lib中的指令全部都被直接包含在最终生成的EXE文件中了;若使用dll,则该dll不必被包含在最终的exe文件中,exe文件执行时可以“动态”地引用和卸载这个与exe独立的dll文件。 静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态链接库,而在动态链接库中还可以再包含其他的动态或静态链接库。,需要注意的是,头文件与库文件都包含函数,但二者存在以下区别: (1) 头文件由编译器使用,库文件由连接器使用; (2) 头文件中的函数为对应的库文件中的函数提供接口(ASCII码),一般包括函数声明、宏定义、类型定义等,库文件中放着函数实现代码编译后的结果

4、(二进制的机器码)。,9.2.1 静态链接库概念 静态链接库不同于动态链接库(*.dll),在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.lib),Visual C+的编译器在链接过程中将从静态库中恢复这些函数和数据并把它们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为“静态链接”,此时因为应用程序所需的全部内容都是从库中复制出来的,所以静态库本身并不需要与可执行文件一起发行。,9.2 静 态 链 接 库,可以说,每一个lib文件就是若干函数(假设只有函数)的定义。完整的可调用的静态链接库最少提供两个文件,即静态库的头文件和静态库的lib文件。,9.2.2 静

5、态链接库设计 创建一个静态链接库可以利用编译器的向导。以VC6.0为例,首先选择“FileNew”菜单,弹出“New”对话框;选择“Projects”标签,在项目类型列表框中选择“Win32 Static Library”项,在“Name”中输入“MyLib”,表明要创建一个MyLib.lib的静态库文件,最后选择“完成”。其他版本的VC编译器与这个过程区别不大。 在工程中最少需要新建 .h和 .cpp两个文件,一个用于对要封装的函数进行声明,一个是函数的实现。下面两段程序就是MyLib.h和MyLib.ccp,封装了函数MyFunc()。,文件MyLib.h如下: #ifndef _MYMA

6、TH_H #define _MYMATH_H extern “C“ int MyFunc(int n); /进行函数的声明 /其他函数的声明 #endif,文件MyLib.ccp如下: #include“MyLib.h“ int MyFunc(int n) return n+=1003; 编译这个工程就得到了一个MyLib.lib文件,这个文件就是一个函数库,它提供了MyFunc功能。将头文件和 .lib文件提交给用户后,用户就可以直接使用其中的函数了。,9.2.3 静态链接库调用 调用静态链接库的方法有两种:一种是通过编译器中的工程设置实现调用,另一种是在程序代码中加入调用语句。两种调用方式

7、都需要将要调用的静态链接库的头文件采用“#include”方法加入文件。 1工程设置调用 在Win32环境下的VC+6.0编译器,以调用netapi32.lib静态链接库为例,在菜单中的“工程”下拉菜单的“设置”项的“Link”选项卡中加入netapi32.lib,如图9-1所示。,图9-1 netapi32.lib设置,在VS2005中,工程调用设置分两步: 右键点击工程名testlib,选择“属性”,弹出“工程属性”框,然后选择“配置属性链接器常规附加库目录”选项,该选项就是用于设置lib所在目录的,添加的目录如图9-2所示; 选择“属性”项,弹出“工程属性”框,然后是“配置属性链接器常规

8、附加依赖”项,该选项就用于指定项目中需要用到的库文件(因为前面已经指定了库文件所在目录),如图9-3所示。,图9-2 VS2005的lib路径设置,图9-3 VS2005的文件设置,对于系统标准库(如包含函数printf的库文件),在程序中调用的时候只要把它的头文件“stdio.h”用“#include”加到程序里就可以了,不用再手工指定,连接器会在编译时自动连接它们,因而调用方法会与后面提及的方法稍有不同。,2程序代码调用 除了上述在编译器中设置lib之外,还可以在使用程序代码中直接调用。使用如下语句进行静态链接库的调用时,应当注意该链接库应当放在编译器可以找到的位置,否则就应当在文件名处把

9、文件的路径写全(假设netapi32.lib放在根目录下)。 #include “stdafx.h“ #include“MyLib.h“ #pragma comment(lib,“MyLib.lib“) /#pragma comment(lib,“C: MyLib.lib“),int main(int argc, char* argv) int a=MyFunc(2); printf (“jiguo is %d“,a); return 0; 这种调用方法比较适合其他程序员对程序源代码的阅读,同样也不适用于系统标准库,9.3.1 动态链接库概念 动态链接库在Windows操作系统中,对于程序执行

10、是非常重要的,因为程序在执行的时候必须链接到dll文件,才能够正确地运行,而有些dll文件可以被许多程序共用。因此,程序设计人员可以利用dll文件,使程序不至于太过巨大。但是当安装的程序越来越多时,dll文件也就会越来越多,当用户删除程序的时候,如果没有用的dll文件没有被删除的话,久而久之就会造成系统的负担。,9.3 动 态 链 接 库,使用动态链接库的一些好处是: (1) 多个应用程序共享代码和数据。比如Office软件的各个组成部分有相似的外观和功能,这就是通过共享动态链接库实现的。 (2) 在钩子(挂钩)程序过滤系统消息时必须使用动态链接库。 (3) 动态链接库以一种自然的方式将一个大

11、的应用程序划分为几个小的模块,这有利于小组内部成员的分工与合作,并且各个模块还可以独立升级。如果小组中的一个成员开发了一组实用例程,他就可以把这些例程放在一个动态链接库中,让小组的其他成员使用。,(4) 为了实现应用程序的国际化,往往需要使用动态链接库。使用动态链接库可以将针对某一国家、语言的信息存放在其中。对于不同的版本,应使用不同的动态链接库。在使用AppWizard生成应用程序时,我们可以指定资源文件使用的语言,这就是通过提供不同的动态链接库实现的。 (5) 拓展研发工具的功能。由于dll是和语言无关的,因此创建一个dll,能够被C+、VB或所有支持动态链接库的语言调用。如果一种语言存在

12、不足,就能通过访问另一种语言创建的dll来弥补。,VC+、C+ Builder、Delphi都可以编写dll文件。dll不是独立运行的程序,它是某个程序的一个部分,它只能由所属的程序调用,用户不能打开它。 生成一个动态链接库时应包含两个文件:*.dll和*.lib。lib是编译时需要的,dll是运行时需要的。如果要完成源代码的编译,有lib就够了。如果要使动态链接的程序运行起来,有dll就够了。lib文件是必须在编译期就链接到应用程序中的,而dll文件是运行期才会被调用的。dll文件包含函数的实现,是可执行的代码。lib文件是dll的一个映像文件,一般包含一些索引信息,如dll导出的函数的名称

13、和位置等。动态链接库有两种调用方式:隐式调用和显示调用。,9.3.2 动态链接库调用 动态链接库调用的方法分隐式和显式两种。 1隐式调用 应用程序使用lib文件链接到所需要使用的dll文件,库中的函数和数据并不复制到exe文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是dll中所要调用的函数的内存地址(lib文件是必需的),下面以动态链接库a为例说明其隐式调用步骤,可分为以下三步: (1) 确保a.dll和a.lib两个文件都存放到了指定目录(这里假设两个文件放在调用该库的应用程序所在目录);,(2) 将要调用函数(假设为test()函数)的文件定位信息(包含在lib文件

14、中)和声明写到调用该库及函数的代码头文件中。 #pragma comment(lib,“a.lib“) /指定该动态链接库相应静态库的文件定位信息 extern “C“_declspec(dllimport) test1); /对需调用的函数进行声明 (3) 进行(2)中的声明后,就可以在文件中调用该函数了。,2显式调用 如果dll没有对应的 .lib文件,那么就只能使用显示调用(动态加载)的方式了,显式调用步骤如下: (1) 创建一个函数指针,其指针数据类型要与调用的dll引出函数相吻合; (2) 通过Win32 API函数LoadLibrary()显式地调用dll,此函数返回dll的实例句

15、柄; (3) 通过Win32 API函数GetProcAddress()获取要调用的dll的函数地址,把结果赋给自定义函数的指针类型; (4) 使用函数指针来调用dll函数;,(5) 调用完成后,通过Win32 API函数FreeLibrary()释放dll函数。 同样,以动态链接库a的test函数为例,下面代码描述了显式调用过程。 typedef int(*test)(); /宏定义声明欲调用函数指针类型, /简要起见这里该函数没有形式参数,HINSTANCE hDll; /Dll句柄 test myFun; /函数指针 hDll=LoadLibrary(“a.dll“); /显式调用dll

16、,a.dll文件放置在应用程序所在目录 if (hDll!=NULL) myFun=(test)GetProcAddress(hDll, “test“); /获取函数地址,if (addFun!=NULL)test(); /函数调用 FreeLibrary(hDll); /释放dll 如前所述,dll正确调用的前提是,需将dll(隐式的还包括lib文件)放入系统可以找到的目录下(系统寻找dll文件的顺序依次为:应用程序所在目录当前目录Windows系统目录PATH环境中设置的其他目录),如果不能找到该dll库文件,则调用势必失败。,9.3.3 动态链接库编程 dll可以简单分为两种类型,即用C/C+(不用对象)编写

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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

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