动态链接库技术(二)

上传人:小** 文档编号:57177680 上传时间:2022-02-23 格式:DOC 页数:5 大小:96.50KB
收藏 版权申诉 举报 下载
动态链接库技术(二)_第1页
第1页 / 共5页
动态链接库技术(二)_第2页
第2页 / 共5页
动态链接库技术(二)_第3页
第3页 / 共5页
资源描述:

《动态链接库技术(二)》由会员分享,可在线阅读,更多相关《动态链接库技术(二)(5页珍藏版)》请在装配图网上搜索。

1、动态链接库技术 ( 二)4. linux 共享对象技术在 linux 操作系统中,采用了很多共享对象技术( shared object ),虽然它和 windows 里的 动态库相对应,但它并不称为动态库。相应的共享对象文件以 .so 作为后缀,为了方便,在本文 中,对该概念不进行专门区分。 linux 系统的 /lib 以及标准图形界面的 /usr/x11r6/lib 等目录里面, 就有许多以 so 结尾的共享对象。同样,在 linux 下,也有静态函数库这种调用方式,相应的后 缀以 .a 结束。 linux 采用该共享对象技术以方便程序间共享,节省程序占有空间,增加程序的可 扩展性和灵活性

2、。 linux 还可以通过 ld-preload 变量让开发人员可以使用自己的程序库中的模块 来替换系统模块。同 windows 系统一样, 在 linux 中创建和使用动态库是比较容易的事情, 在编译函数库源程 序时加上 -shared 选项即可,这样所生成的执行程序就是动态链接库。通常这样的程序以 so 为 后缀,在 linux 动态库程序设计过程中,通常流程是编写用户的接口文件,通常是 .h 文件,编写 实际的函数文件,以 .c 或 .cpp 为后缀,再编写 makefile 文件。对于较小的动态库程序可以不用 如此,但这样设计使程序更加合理。编译生成动态连接库后, 进而可以在程序中进行

3、调用。 在 linux 中,可以采用多种调用方式, 同 windows 的系统目录 (.system32 等 )一样, 可以将动态库文件拷贝到 /lib 目录或者在 /lib 目录 里面建立符号连接,以便所有用户使用。下面介绍 linux 调用动态库经常使用的函数,但在使用 动态库时,源程序必须包含 dlfcn.h 头文件,该文件定义调用动态链接库的函数的原型。(1) _ 打开动态链接库: dlopen ,函数原型 void *dlopen (const char *filename, int flag);dlopen 用于打开指定名字 (filename) 的动态链接库,并返回操作句柄。(2

4、) 取函数执行地址: dlsym ,函数原型为 : void *dlsym(void *handle, char *symbol);dlsym 根据动态链接库操作句柄 (handle) 与符号 (symbol) ,返回符号对应的函数的执行代码地址。(3) 关闭动态链接库: dlclose ,函数原型为 : int dlclose (void *handle);dlclose 用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0 时 ,才会真正被系统卸载。(4) 动态库错误函数: dlerror ,函数原型为 : const char *dlerror(void);当动态链接库操作函数

5、执行失败时, dlerror 可以返回出错信息,返回值为 null 时表示操作函数执行成功。在取到函数执行地址后, 就可以在动态库的使用程序里面根据动态库提供的函数接口声明调 用动态库里面的函数。 在编写调用动态库的程序的 makefile 文件时,需要加入编译选项 -rdynamic 和 -ldl 。除了采用这种方式编写和调用动态库之外, linux 操作系统也提供了一种更为方便的动态库 调用方式,也方便了其它程序调用,这种方式与 windows 系统的隐式链接类似。其动态库命名 方式为 “lib*.so.* 。”在这个命名方式中,第一个 *表示动态链接库的库名,第二个 * 通常表示该动 态

6、库的版本号,也可以没有版本号。在这种调用方式中,需要维护动态链接库的配置文件 /etc/ld.so.conf 来让动态链接库为系统所使用,通常将动态链接库所在目录名追加到动态链接库 配置文件中。 如具有 x window 窗口系统发行版该文件中都具有 /usr/x11r6/lib ,它指向 x window 窗口系统的动态链接库所在目录。 为了使动态链接库能为系统所共享, 还需运行动态链接库的管 理命令./sbin/Ideonfig 。在编译所引用的动态库时,可以在gee采用 -或-1选项或直接引用所需的动态链接库方式进行编译。在 linux 里面,可以采用 ldd 命令来检查程序依赖共享库。

7、5. 简单实例。5.1 Iinux 创建动态库5.1.1 将步骤 3.1.1 创建的项目 dyIi 拷贝到 Iinux 系统某目录下,考虑到 windows 与 Iinux 的互相移植 ,拷贝之前修改 StdAfx.h 文件内容。#if !defined(AFX_STDAFX_H_A53E2366_5868_4675_82D8_9D1A26A1E8EB_INCLUDE D_)#define AFX_STDAFX_H_A53E2366_5868_4675_82D8_9D1A26A1E8EB_INCLUDED_#ifdef WIN32#if _MSC_VER 1000#pragma onee#en

8、dif / _MSC_VER 1000/ Insert your headers here#define WIN32_LEAN_AND_MEAN / ExeIude rareIy-used stuff from Windows headers#ineIude #endif/ TODO: referenee additionaI headers your program requires here#endif/ !defined(AFX_STDAFX_H_A53E2366_5868_4675_82D8_9D1A26A1E8EB_INCLUDED_)5.2.2 编写 makefiIe 文件 :DE

9、ST=IibdyIi.aOBJS=dyIi.oCC= g+CPPFLAGS = -O2 -WallSHAREFLAGS = -shared -fPIC INCLUDES = -I.$(DEST) : $(OBJS)$(CC) $(SHAREFLAGS) $(INCLUDES) $(CPPFLAGS) -o $ $Adyli.o : dyli.cpp dyli.h$(CC) $(INCLUDES) $(CPPFLAGS) -c $ -o $5.2.3 make 编译生成 libdyli.a 文件。5.3 linux 调用动态库5.3.1 新建测试文件 testlib.cpp ,并将 libdyl

10、i.a, dyli.h 文件拷贝到测试文件夹下 cat testlib.cpp#include #include dyli.hint main(int argc, char* argv)int tt = add(5,6); printf(5+6= %d n,tt);return 0;5.3.2 新建 makefile 文件cat makefileDEST=testlibOBJS=testlib.oCC= g+CPPFLAGS = -O2 -WallINCLUDES = -I.LIBS =-L. -ldyli$(DEST) : $(OBJS)$(CC) $(INCLUDES) $(LIBS) $

11、(CPPFLAGS) -o $ $Atestlib.o : testlib.cpp$(CC) $(INCLUDES) $(CPPFLAGS) -c $ -o $5.3.3 make 编译生成可执行文件 testlib, 运行测试成功。6 、两种系统动态库比较分析windows 和 linux 采用动态链接库技术目的是基本一致的,但由于操作系统的不同,他们在 许多方面还是不尽相同,下面从以下几个方面进行阐述。(1) 动态库程序编写, 在 windows 系统下的执行文件格式是 pe 格式,动态库需要一个 dllmain 函数作为初始化的人口,通常在导出函数的声明时需要有 _declspec(dl

12、lexport) 关键字。 linux 下 的 gcc 编译的执行文件默认是 elf 格式,不需要初始化入口,亦不需要到函数做特别声明,编写 比较方便。(2) 动态库编译,在 windows 系统下面,有方便的调试编译环境,通常不用自己去编写 makefile 文件,但在 linux 下面,需要自己动手去编写 makefile 文件,因此,必须掌握一定的 makefile 编写技巧,另外,通常 linux 编译规则相对严格。(3) 动态库调用方面, windows 和 linux 对其下编制的动态库都可以采用显式调用或隐式调 用,但具体的调用方式也不尽相同。(4) 动态库输出函数查看,在 wi

13、ndows 中,有许多工具和软件可以进行查看 dll 中所输出的 函数,例如命令行方式的 dumpbin 以及 vc+ 工具中的 depends 程序。 在 linux 系统中通常采用 nm 来查看输出函数,也可以使用 ldd 查看程序隐式链接的共享对象文件。(5) 对操作系统的依赖,这两种动态库运行依赖于各自的操作系统,不能跨平台使用。因此, 对于实现相同功能的动态库,必须为两种不同的操作系统提供不同的动态库版本。7、动态库移植方法如果要编制在两个系统中都能使用的动态链接库, 通常会先选择在 windows 的 vc+ 提供的 调试环境中完成初始的开发, 毕竟 vc+ 提供的图形化编辑和调试

14、界面比 vi 和 gcc 方便许多。 完 成测试之后, 再进行动态库的程序移植。 通常 gcc 默认的编译规则比 vc+ 默认的编译规则严格, 即使在 vc+ 下面没有任何警告错误的程序在 gcc 调试中也会出现许多警告错误,可以在 gcc 中 采用 -w 选项关闭警告错误。下面给出程序移植需要遵循的规则以及经验。(1) 尽量不要改变原有动态库头文件的顺序。通常在 c/c+ 语言中,头文件的顺序有相当的 关系。另外虽然 c/c+ 语言区分大小写,但在包含头文件时, linux 必须与头文件的大小写相同, 因为 ext2 文件系统对文件名是大小写敏感,否则不能正确编译,而在 windows 下面

15、,头文件大 小写可以正确编译。(2) 不同系统独有的头文件。在 windows 系统中,通常会包括 windows.h 头文件,如果调用 底层的通信函数,则会包含 winsock.h 头文件。因此在移植到 linux 系统时,要注释掉这些windows 系统独有的头文件以及一些 windows 系统的常量定义说明, 增加 linux 都底层通信的支 持的头文件等。(3) 数据类型。 vc+ 具有许多独有的数据类型,如_int16 , _int32 ,true , socket 等, gcc编译器不支持它们。 通常做法是需要将 windows.h 和 basetypes.h 中对这些数据进行定义

16、的语句 复制到一个头文件中,再在 linux 中包含这个头文件。例如将套接字的类型为 socket 改为 int 。(4) 关键字。 vc+ 中具有许多标准 c 中所没有采用的关键字, 如 bool ,byte ,dword ,_asm 等,通常在为了移植方便,尽量不使用它们,如果实在无法避免可以采用#ifdef和#6门dif为linux和 windows 编写两个版本。(5) 函数原型的修改。通常如果采用标准的 c/c+ 语言编写的动态库,基本上不用再重新编写函数,但对于系统调用函数,由于两种系统的区别,需要改变函数的调用方式等,如在linux编制的网络通信动态库中,用 close() 函数

17、代替 windows 操作系统下的 closesocket() 函数来关闭 套接字。另外在 linux 下没有文件句柄,要打开文件可用 open 和 fopen 函数,具体这两个函数 的用法可参考文献 2 。(6) makefile 的编写。在 windows 下面通常由 vc+ 编译器来负责调试,但 gcc 需要自己动手编写 makefile 文件,也可以参照 vc+ 生成的 makefile 文件。对于动态库移植,编译动态库 时需要加入 -shared 选项。 对于采用数学函数,如幂级数的程序, 在调用动态库是, 需要加入 -lm。(7) 其它一些需要注意的地方 程序设计结构分析,对于移植

18、它人编写的动态库程序,程序结构分析是必不可少的步骤, 通常在动态库程序中,不会包含界面等操作,所以相对容易一些。 在 linux 中,对文件或目录的权限分为拥有者、群组、其它。所以在存取文件时,要注意 对文件是读还是写操作, 如果是对文件进行写操作, 要注意修改文件或目录的权限, 否则无法对 文件进行写。 指针的使用, 定义一个指针只给它分配四个字节的内存, 如果要对指针所指向的变量赋值,必须用 malloc 函数为它分配内存或不把它定义为指针而定义为变量即可,这点在linux 下面比windows 编译严格。同样结构不能在函数中传值,如果要在函数中进行结构传值,必须把函数 中的结构定义为结构

19、指针。 路径标识符,在linux下是“/;在windows下是“”,注意windows和linux的对动态库搜索路径的不同。 编程和调试技巧方面。对不同的调试环境有不同的调试技巧,在这里不多叙述。8、结束语本文系统分析了 windows 和 linux 动态库实现和使用方式, 从程序编写、 编译、 调用以及对 操作系统依赖等方面综合分析比较了这两种调用方式的不同之处,根据实际程序移植经验, 给出 了将 vc+ 编制的 windows 动态库移植到 linux 下的方法以及需要注意的问题,同时并给出了程 序示例片断, 实际在程序移植过程中, 由于系统的设计等方面, 可能移植起来需要注意的方面远 比上面复杂,本文通过总结归纳进而为不同操作系统程序移植提供了有意的经验和技巧。

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!