程序员的自我修养(十二) -- Linux共享库

共享库

从文件结构上来看,共享库和共享对象没什么区别,Linux下的共享库就是欧通的ELF共享对象。

共享库的更新有两类:

  1. 兼容更新
  2. 不兼容更新

版本命名:
libname.so.x.y.z
x:主版本号 //库的重大升级,不同主版本号之间是不兼容的
y:次版本号 //库的增量升级。向下兼容
z:发布版本号 //表示库的一些错误修正、性能的改进等,并不添加新的接口,也不对接口进行更改。
相同主版本号、次版本号的共享库,不同发布版本号之间可以完全兼容

程序如何记录共享库依赖?

SO-NAME:共享库的文件名去掉次版本号和发布版本号,保留主版本号。【libfoo.so.3.2.111,它的SO-NAME为libfoo.so.3】
在Linux系统中,系统会为每个共享库在它所在的目录创建一个跟“SO-NAME”相同的并且指向它的软链接【这样做可以使得以来某个共享库的模块,在编译、链接欸和运行时,都使用共享库的SO-NAME,而不使用详细的版本号】

基于符号的版本机制:基本思路是,让每个导出和导入的符号都有一个相关联的版本号

共享库的系统路径

大多数包括Linux在内的开源操作系统都遵循一个叫做FHS的标准。
共享库的位置一般为:

  • /lib:这里主要存放系统最关键和最基础的共享库。【比如动态链接器、C语言运行时库、数学库等】
  • /usr/lib:这里主要保存一些非系统运行时需要的关键性的共享库【主要是开发时用到的共享库】
  • /usr/local/lib:这里保存一些跟操作系统本身并不十分相关的库,主要是一些第三方的应用程序的库
共享库的查找过程

动态链接器对于模块的查找规则:
如果DT_NEED里面保存的是绝对路径,那么动态链接器就按照这个路径查找;
如果D_NEED里面保存的是相对路径,那么东爱链接库就会在/lib、/usr/lib和由 /etc/ld.so.config配置文件指定的目录中查找共享库。

查找过程:
会先查找 /etc/ld.so.cache【这个文件用来集中保存共享库的SO-NAME】 ,如果没有,就按照上面的规则查找。

环境变量

LD_LIBRARY_PATH :由若干个路径组成的环境变量。每个路径之间用冒号隔开
如果我们为某个进程设置了LD_LIBRARY_PATH那么,程序启动时,动态链接器在查找共享库时,会首先找由LD_LIBRARY_PATH指定的目录。
指定LD_LIBRARY_PATH
$ LD_LIBRARY_PATH=/home/user /bin/ls

LD_PRELOAD :指定预先装在的一些共享库或者目标文件。【它比LD_LIBRARY_PATH中指定的目录中的共享库还要有限】

LD_DEBUG :打开动态链接器的调试功能

共享库的创建

共享库的创建过程和.so的创建过程基本一致。记得加-shared 和 -fPIC

共享库的构造和析构函数
构造:在函数声明时加上__attribute__((constructor))
它会在共享库被加载时被执行,【即main函数执行之前】如果用dlopen()打开共享库,那么共享构造函数会在dlopen返回之前被执行。
析构:在函数声明时加上__attribute__((destructor))
注意:如果我们使用了这种构造或析构函数,那么必须使用系统默认的标准运行库启动文件【即不可以用“-nostartfiles”或“nosdlib”这两个参数】。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值