linux动态链接

在程序中总会用到各式各样的库,有两种使用方式:静态链接库和动态链接库,在windows下分别对应.lib文件和.dll文件,使用静态库时需要包含对应的头文件并引用lib文件,使用动态库则需要手动通过函数加载dll中的函数。
linux下使用方法则有所不同,linux下.a文件.so文件分别对应静态和动态链接库。

静态链接库

ar rcs libmylib.a mylib.o 生成.a静态库
gcc -o hello main.c -L. -lmylib 生成可执行文件hello;gcc会在mylib之前自动添加lib,即找文件libmylib.a
./hello 执行

可以发现即使删除libmylib.a文件,hello也可以执行。

动态链接库

gcc -fPIC -shared -o libmylib.so mylib.c 生成.so动态库
gcc -o hello main.c -L. -lmylib 生成可执行文件hello;gcc会在mylib之前自动添加lib,即找文件libmylib.so
./hello 执行
./hello: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory

可以发现此时hello执行出错,gcc编译时优先链接动态库文件,但程序执行时并没有找到动态链接库
在linux下程序搜索动态链接库是按照如下顺序的:

  • ELF可执行文件中动态段中DT_RPATH所指定的路径,编译时gcc加入链接参数“-Wl,-rpath”指定该动态库搜索路径
  • 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  • 配置文档/etc/ld.so.conf中指定的动态库搜索路径
  • 默认的动态库搜索路径/lib
  • 默认的动态库搜索路径/usr/lib

按照第一种方法解决,

gcc -o hello main.c -L. -lmylib -Wl,-rpath=. 参数-Wl,-rpath=. 指定当前路径为动态库搜索路径
./hello 可执行

按照第二种方法解决,

export LD_LIBRARY_PATH=.
./hello 可执行

使用命令 readelf -d hello可见其搜索路径 Library rpath: [.]

Dynamic section at offset 0x7b0 contains 22 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libmyhello.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [.]
 0x000000000000000c (INIT)               0x400490
 0x000000000000000d (FINI)               0x4006b8
 0x000000006ffffef5 (GNU_HASH)           0x400260

第三种方法,

把当前路径写入/etc/ld.so.conf,并执行ldconfig重新加载

第四种方法,

把libmylib.so文件拷贝到/lib中

第四种方法,

把libmylib.so文件拷贝到/lib中

第五种方法,

把libmylib.so文件拷贝到/usr/lib中

在实际使用中第一和第二种方法最经常被采纳,但是使用变量LD_LIBRARY_PATH时要注意,一旦LD_LIBRARY_PATH变量被设置之后,该变量生效范围内的所有程序执行时都会先查找该变量所指定的搜索目录,这样势必会造成一些浪费。

参考http://www.eefocus.com/book/09-04/716171276059628.html
http://blog.chinaunix.net/uid-23592843-id-223539.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值