Linux 静态库 共享库 动态库 读书笔记

来源:互联网 发布:ubuntu安装cuda caffe 编辑:程序博客网 时间:2024/04/28 19:33

静态函数库是在程序执行前就加入到目标程序中去了;而共享函数库则是在程序启动的时候加载到程序中,它可以被不同的程序共享;动态加载函数库则可以在程序运行的任何时候动态的加载。

 

静态函数库实际上就是简单的一个普通的目标文件的集合,一般来说习惯用“.a”作为文件的后缀。可以用ar这个程序来产生静态函数库文件。


静态库函数允许程序员把程序link起来而不用重新编译代码,节省了重新编译代码的时间


理论上说,使用ELF格式的静态库函数生成的代码可以比使用共享函数库(或者动态函数库)的程序运行速度上快一些,大概1-5%。

创建一个静态函数库文件,或者往一个已经存在地静态函数库文件添加新的目标代码,可以用下面的命令:
ar rcs my_library.a file1.o file2.o

 

共享函数库中的函数是在当一个可执行程序在启动的时候被加载。
每个共享函数库都有个特殊的名字,称作“soname”。Soname名字命名必须以“lib”作为前缀,然后是函数库的名字,然后是“.so”,最后是版本号信息。不过有个特例,就是非常底层的C库函数都不是以lib开头这样命名的。

 

一旦你有一个共享函数库,你还需要安装它。其实简单的方法就是拷贝你的库文件到指定的标准的目录(例如/usr/lib),然后运行ldconfig。

 

我们可以通过运行ldd来看某个程序使用的共享函数库。ldd ./owb

 

Linux系统下,DL函数库与其他函数库在格式上没有特殊的区别,我们前面提到过,它们创建的时候是标准的object格式。主要的区别就是这些函数库不是在程序链接的时候或者启动的时候加载,而是通过一个API来打开一个函数库,寻找符号表,处理错误和关闭函数库
一种方法是使用glibc函数库中的对动态加载模块的支持,它使用一些潜在的动态加载函数库界面使得它们可以夸平台使用。
另外一个方法是使用libltdl,是GNU libtool的一部分,可以进一步参考CORBA相关资料。

dlopen函数打开一个函数库然后为后面的使用做准备
dlerror()函数,我们可以获得最后一次调用dlopen(),dlsym(),或者dlclose()的错误信息
dlsym(),这个函数在一个已经打开的函数库里面查找给定的符号
标准的判断方法是先 调用dlerror(),清除以前可能存在的错误,然后调用dlsym()来访问一个symbol,然后再调用dlerror()来判断是否出现了错误。
dlclose()函数用力关闭一个DL函数库。

 

 

nm命令可以列出一个函数库文件中的符号表
符号的类型是以一个字母的形式显示的,小写字母表示这个符号是本地(local)的,而大写字母则表示这个符号是全局的(global,externel)。
一般来说,类型有一下几种:T、D、B、U、W。各自的含义如下:T表示在代码段中定义的一般变量符号;D表示时初始化过的数据段;B表示初始化的数据段;U表示没有定义的,在这个库里面使用了,但是在其他库中定义的符号;W,weak的缩写,表示如果其他函数库中也有对这个符号的定义,则其他符号的定义可以覆盖这个定义。


可以用mn的“-o”选项和grep命令来查找库的名字。-o选项使得显示的每一行都有这个函数库文件名。
nm -o /lib/* /usr/lib/* /usr/lib/*/* /usr/local/lib/* 2> /dev/null | grep 'cos$'

如果你正在编译的系统想很方便的移植到其他操作系统下,你可以使用GNU libtool来创建和安装这个函数库。

 

一旦你完全测试完毕了,就可以用strip去删除一些不需要的符号了。Strip命令可以使你很方便的控制删除什么符号,而保留什么符号。另外的方法就是使用GNU ld的选项“-S”和“-s”;“-S”会删除一些debugger的符号,而“-s”则是将所有的符号信息都删除。通常我们可以在gcc中加这样的参数“-Wl,-S”和“-Wl,-s”来达到这个目的。

原创粉丝点击