Linux平台C/C++ 动态库的制作与使用方式

《Linux平台如何制作自己的C/C++静态库》中简单介绍了静态库的制作方法,但实际上动态库的使用更为广泛,至于原因,在《Linux平台基于C/C++的静态库和动态库的区别》一文中已有说明。本文介绍动态库的制作方法以及两种使用方式。

1. 示例程序

test.c代码如下:

#include"test.h"
void test()
{
    printf("I am test;hello,编程珠玑
");
}

test.h代码如下:

#include
void test();

代码比较简单,只有一个test函数,用于打印一段字符串。

2. 制作动态库

只需要执行以下命令即可:

$ 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。

3. 使用动态库

常见有两种使用方式,一种是加载时链接,另一种是使用时链接。

3.1 加载时链接

加载时链接在代码中不需要做额外的动作,像使用静态库一样使用即可。例如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

它并不能找到这个动态库,因为它会默认从系统库的路径去查找这个库,但是我们并没有把这个库放到系统路径下,因此会找不到了。

我们有两种方法解决这个问题:

  • 将libtest.so库放到系统路径下
  • 指定当前进程动态库搜索路径

第一种方法:

$ 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了。

3.2 使用时链接

为了使用这种方式,需要使用几个函数dlopen,dlsym,dlclose,dlerror,其原型分别如下:

  • 分享于 2019-07-29 13:43
  • 阅读 ( 223 )

[版权声明] :本文系网友分享,仅以非商业性的交流和科研为目的,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本网( friends@stuch.cn )联系!我们将协调给予处理。阅读原文(请登录)..

0 条评论

请先 登录 后评论
猜猜我是谁
甜也 -研究生

9
提问
7
回答
4
文章