在 《Linux 平台如何制作自己的 C /C++ 静态库》 中简单介绍了静态库的制作方法,但实际上动态库的使用更为广泛,至于原因,在 《Linux 平台基于 C /C++ 的静态库和动态库的区别》 一文中已有说明。本文介绍动态库的制作方法以及两种使用方式。
test.c 代码如下:
#include"test.h"
void test()
{
printf("I am test;hello,编程珠玑
");
}
test.h 代码如下:
#include
void test();
代码比较简单,只有一个 test 函数,用于打印一段字符串。
只需要执行以下命令即可:
$ gcc test.c -fPIC -shared -o libtest.so
其中的 -fPIC 表示生成位置无关代码,以便在只有一个副本的情况下供多个应用程序共享。
通过 readelf 命令查看 elf 文件类型:
$ readelf -h libtest.so
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
从结果中可以看到,libtest.so 为 Shared object file。
常见有两种使用方式,一种是加载时链接,另一种是使用时链接。
加载时链接在代码中不需要做额外的动作,像使用静态库一样使用即可。例如 main.c 如下:
#include
#include"test.h"
int main(void)
{
test();
return 0;
}
编译链接:
$ gcc -o main main.c -L . -ltest
其中 - L 指定从当前目录下寻找动态库 libtest.so,否则会找不到。
然后我们还可以通过 ldd 命令查看其依赖的动态库:
$ ldd main
Linux-vdso.so.1 => (0x00007ffd57757000)
libtest.so => not found
libc.so.6 => /lib/x86_64-Linux-gnu/libc.so.6 (0x00007f84c13f6000)
/lib64/ld-Linux-x86-64.so.2 (0x00007f84c17c0000)
其中就有我们自己制作的 libtest.so。
运行:
$ ./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
很不幸,程序并没有如预期的那样运行起来,而是报错了。这是为什么呢?
其实我们在使用 ldd 命令查看的时候,就注意到:
libtest.so => not found
它并不能找到这个动态库,因为它会默认从系统库的路径去查找这个库,但是我们并没有把这个库放到系统路径下,因此会找不到了。
我们有两种方法解决这个问题:
第一种方法:
$ cp libtest.so /usr/lib
$ ./main
I am test;hello,编程珠玑
第二种方法:
$ export LD_LIBRARY_PATH=./
$ ./main
I am test;hello,编程珠玑
导入 LD_LIBRARY_PATH 环境变量,指定库搜索路径,使得 main 程序能够找到 libtest.so。
此时再看:
$ ldd main
Linux-vdso.so.1 => (0x00007ffcdebdf000)
libtest.so => ./libtest.so (0x00007f494a45f000)
libc.so.6 => /lib/x86_64-Linux-gnu/libc.so.6 (0x00007f494a095000)
/lib64/ld-Linux-x86-64.so.2 (0x00007f494a661000)
libtest.so 不再是 not found 了。
为了使用这种方式,需要使用几个函数 dlopen,dlsym,dlclose,dlerror,其原型分别如下:
[版权声明] :本文系网友分享,仅以非商业性的交流和科研为目的,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本网( friends@stuch.cn )联系!我们将协调给予处理。转载授权码:确权中,请原作者尽快与我们取得联系,阅读原文(请登录)..