linux动态链接库的编译和使用

1. 动态链接库的编译

实现加法运算的动态库:

mylib.c

#include "mylib.h"

int add(int i, int k)
{
   return i + k;
}

mylib.h

#ifndef MYLIB_H_
#define MYLIB_H_
 
int add(int i, int k);
 
#endif

编译命令:

mkdir build
gcc mylib.c -shared -g -o ./build/libmylib.so

2. 可执行程序的编译

main.c

#include <stdio.h>
#include "mylib.h"
 
int main()
{
    int a = add(1, 2);
    printf("a:%d\n", a);
    return 0;
}

编译命令:

gcc main.c -lmylib -L ./build -g -o ./build/main.out

此时文件树如下:
在这里插入图片描述

3. 运行可执行程序

此时直接运行main.out会报错:error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory,即找不到libmylib.so,这是因为当前so所在目录不在程序运行时查找路径范围内,因为需要告诉程序运行时到哪个目录查找动态库。
在这里插入图片描述

4. 设置动态库查询目录

方法一:更改环境变量LD_LIBRARY_PATH

LD_LIBRARY_PATH用于在程序运行期间查找动态库的路径,我们可以把libmylib.so放到/usr/local/lib64目录下,并把/usr/local/lib64目录写到LD_LIBRARY_PATH中即可:

export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH

可以执行echo $LD_LIBRARY_PATH确认下已经添加成功:
在这里插入图片描述
此时执行main.out即可通过:
在这里插入图片描述

方法二:通过-Wl,-rpath编译链接选项指定

有些时候我们并不想把每个so都放到/usr/local/lib64目录下,只是临时执行个程序,或者不想让其他用户看到自己的so,就可以在编译可执行程序的时候通过-Wl,-rpath编译链接选项告诉编译器,程序运行时去我指定的目录下查找so:

gcc main.c -Wl,-rpath=./build/ -lmylib -L ./build -g -o ./build/main.out

比如我的so和main.out都放在./build目录下,-Wl,-rpath=./build/告诉链接器运行时去./build目录下查找libmylib.so,再执行./build/main.out即可通过。

方法三:修改配置文件/etc/ld.so.conf

/etc/ld.so.conf文件是告诉系统运行时查询so目录的配置文件,可以把so所在的目录加到这个配置文件后面,以后无论机器是否关机,都能够正常执行:
在这里插入图片描述
/etc/ld.so.conf文件更改之后,需要执行下ldconfig刷新动态库查询目录缓存(/etc/ld.so.cache),然后再执行./build/main.out即可通过。
说明:这里有个坑,如果把/etc/ld.so.conf指定的A目录下的so删除(且可执行文件用的恰好是这个so),但是在/etc/ld.so.conf指定的B目录中还有一份同名so时,系统并不会自动查找B目录的so(即使并没有更改/etc/ld.so.conf文件),此时需要再次执行一次ldconfig。猜测ldconfig命令在/etc/ld.so.conf的某一行查找到动态库后就不会再检测后续行了,所以缓存中并没有保存B目录的so路径,必须重新执行ldconfig刷新缓存才行。

方法四:把so放到系统默认查询目录下/lib, /lib64, /usr/lib, /usr/lib64

其实在/etc/ld.so.conf文件最后的注释写了,/lib, /lib64, /usr/lib, /usr/lib64是系统默认的动态库查询目录,即使环境变量、-Wl,-rpath、/etc/ld.so.conf都不修改,直接把so放到这4个目录里,系统也能自动查找到的。
注意:如果放进去后还是执行不通过,再执行下ldconfig刷新下缓存。

说明:可以使用ldd命令查询二进制文件(包括可执行文件、so文件)依赖哪些so,以及对应的内存地址:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值