以前搞共享库动态加载管理时找的一些资料,放在这里共享。
引言:
在xmeeting中,关于usb手柄部分,采用动态库调用方式,下面翻译一篇David A. Wheeler写的文章。文章就如何创建和使用静态库,共享库以及动如何动态装载库进行了论述。内容纲要如下:
1.概述
2.静态库
3.共享库
3.1 约定
3.2 使用
3.3 环境变量
3.4 创建共享库
3.5 安装与使用
3.6 兼容性
4.动态加载
4.1 dlopen()
4.2 dlerror()
4.3 dlsym()
4.4 dlclose()
4.5 示例
5.辅助知识
5.1 nm命令
5.2 库的构建与析构函数
5.3 脚本
5.4 版本
5.5 GNU libtool
5.6 去除符号空间
5.7 外部执行体
5.8 C++ 与 C
5.9 加速C++初始化
5.10 Linux标准
1.概述
本文就如何在Linux系统中运用GNU工具创建和使用程序库进行论述。所谓"程序库",简单说,就是包含了数据和执行码的文件。其不能单独执行,可以作为其它执行程序的一部分,来完成执行功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码重用,可以使得程序便于升级。程序库可分三类:静态库,共享库和动态加载库。
静态库,是在执行程序运行前就已经加入到执行码中,在物理上成为执行程序的一部分;共享库,是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。动态加载库,其实并不是一种真正的库类型,应该是一种库的使用技术,应用程序可以在运行过程中随时加载和使用库。
建议库开发人员创建共享库,比较明显的优势在于库是独立的,便于维护和更新;而静态库的更新比较麻烦,一般不做推荐。然而,它们又各有优点,后面会讲到。在C++编程中,要使用动态加载技术,需要参考文章"C++ dlopen MINI-Howto"。
文章中讲述的执行程序和库都采用ELF(Executable and Linking Format)格式,尽管GNU GCC 工具可以处理其它格式,但不在本文的讨论范围。本文可以在 http://www.dwheeler.com/program-library 和http://www.linuxdoc.org 找到。
2.静态库
静态库可以认为是一些目标代码的集合。按照习惯,一般以".a"做为文件后缀名。使用ar(archiver)命令可以创建静态库。因为共享库有着更大的优势,静态库已经不被经常使用。但静态库使用简单,仍有使用的余地,并会一直存在。
静态库在应用程序生成时,可以不必再编译,节省再编译时间。但在编译器越来越快的今天,这一点似乎已不重要。如果其他开发人员要使用你的代码,而你又不想给其源码,提供静态库是一种选择。从理论上讲,应用程序使用了静态库,要比使用动态加载库速度快1-5%,但由于莫名的原因,实际上可能并非如此。由此看来,除了使用方便外,静态库可能并非一种好的选择。
要创建一个静态库,或要将目标代码加入到已经存在的静态库中,可以使用以下命令:
ar rcs my_libraty.a file1.o file2.o
以上表示要把目标码file1.o和file2.o加入到静态库my_library.a中。若my_library.a不存在,会自动创建。
静态库创建成功后,需要连接到应用程序中来使用。如果你使用gcc(1)来产生执行程序,需要利用-l选项来指定静态库。更多信息,查看gcc使用手册。
在使用gcc时,要注意其参数的顺序。-l是连接器选项,一定要放在被编译的文件名称之后;若放在文件名称之前,你会连接失败,并会出现莫名其妙的错误。这一点切记。
你也可以直接使用连接器ld(1),使用其选项-l或-L。但最好使用gcc(1),因ld(1)的接口有可能会有变化。
3.共享库
共享库是在程序启动时被装载。当一个应用程序装载了一个共享库后,其它应用程序仍可以装载同一个共享库。基于linux的使用方法,共享库还有其它灵活的而又精妙的特性:
更新库并不影响应用程序使用旧的,非向后兼容的版本;
在执行特定程序时,可以覆盖整个库或更新库中的特定函数;
以上操作不会影响已经运行的程序,他们仍会使用已经装载的库。
3.1约定
要想共享库具有以上特性,一些约定需要遵守。你需要掌握共享库名称之间的区别,特别是搜名(soname)和实名(realname)之间的区别和关系;你还需要知道共享库在文件系统的位置。
3.1.1名称
每个共享库都有一个特定的搜名(soname),其组成如下:
lib + 库名 + .so + . + version
| | |_______________|
前缀 库名 后缀
在文件系统中,搜名是一个指向实名的符号联结。
每个共享库也有一个实名,其真正包含有库的代码,组成如下:
搜名 + . + 子版本号 + . + 发布号
最后的句点和发布