Linux系统下分为两种类型的函数库:
1. 静态库
静态库的链接工作是在程序编译阶段完成的。
每个需要调用该静态库的程序中都有一份该库的拷贝,
所以静态库在程序中的绝对位置在编译阶段就确定下来了;
由于多个程序中同时有多份静态库的拷贝,所以增大了程序的大小。
2. 动态链接库
动态链接库在程序编译阶段不会被拷贝到程序中。
它是程序在运行阶段需要调用库时才去将函数库链接到可执行程序中的。
由于它是动态加载的,所以它在程序中的绝对位置是不确定的;
但是函数库内部的各个函数之间的相对位置是在编译期间确定下来的。
动态链接库需要操作系统的支持,幸运的是现在的操作系统基本上都支持动态链接库。
由于是程序运行时根据需要实时的载入库,
所以如果函数库找不到或者函数库中缺少某个库函数都会造成程序执行错误。
对于动态链接库来讲,这样的错误只能在程序运行时才能被发现。
如果是静态库,则这些错误可以在程序编译阶段被提早发现。
使用动态链接库的好处有:
1. 真正的实现了函数库和程序的分离,库函数提供者不必关心程序的其它部分。
他们只需要提供可用的动态函数库即可。
2. 让程序的升级变得简单
如果动态链接库有改动,不必去编译整个可执行程序,让程序开发变得方便简单。
用户只需要编译这个动态链接库,然后将其copy到动态链接库原本的存放位置,重新运行程序即可。
接下来就具体学习如何应用动态链接库的这个特性,以方便程序开发。
具体步骤如下:
1. 确定所使用的函数库所在的系统的位置,可以使用find命令进行查找
sh-3.2# find / -name “libtest.so”
2. 将编译好的.so文件copy到对应的步骤1找到的位置,
sh-3.2# mount -o sync -t vfat /dev/sda1 /mnt/
其中参数-o带sync参数用来指定该分区是以sync方式进行写操作;
参数-t用来指定待mount的分区的文件系统类型。
3. 重新运行这个程序,这时程序就是加载了新的动态链接库运行了。
4. 使用ldd命令可以用来查看程序依赖于哪些动态链接库
sh-# ldd ./test_main
libc.so.6 => /lib/libc.so.6 (0x40113000)
/lib/ld-linux.so.3 (0x40022000)
sh-#
关于ldd可以参考下面这篇文章, http://www.linuxidc.com/Linux/2014-01/94718.htm
如果程序很庞大,如何确认某个模块或某个函数是属于哪一个动态链接库(在一个很大系的统中是有可能的)?
假定函数位于某个动态链接库中,则可以使用objdump将动态链接库进行反汇编,然后在结果中查找指定的函数,
sh-3.2# objdump -d ./libtest.so | grep function
使用readelf或nm都无法准确的定位函数处于哪个.so文件中,
sh-3.2# readelf -s ./libtest.so | grep function
sh-3.2# nm ./libtest.so | grep function
原因是这个符号既会在函数所在的库中查到,同时在调用这个函数的库中也能查到。
相关阅读:
控制Linux动态链接库导出函数 http://www.linuxidc.com/Linux/2013-04/83614.htm
Ubuntu下的进行动态链接库创建和使用的方法 http://www.linuxidc.com/Linux/2013-04/83293.htm
Linux动态链接库导出函数 http://www.linuxidc.com/Linux/2013-04/82653.htm
Linux下使用动态链接库 http://www.linuxidc.com/Linux/2013-02/79669.htm
Linux下面系统开发Makefile须知(动态链接库的深入理解) http://www.linuxidc.com/Linux/2012-12/76158.htm