LINUX系统编程:静态库和动态库的使用

  通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。本文主要通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们。

  1. 自定义库函数源文件add.c 代码清单
int add(int a,int b)
{
    int c=0;
    c = a + b;
    return c;
}
  1. 主程序源文件main.c代码如下
#include <stdio.h>
int add(int a,int b);

int main(void)
{
    int i = 0;
    for(i=0; i < 20; i++) {
        int sum = add(110,i);
        printf("sum:%d\n",sum);
    }
    return 0;
}
  1. 编译生成静态库文件

编译生成目标文件
[csy@local libtest]$ gcc -c add.c
把add.o编译成静态链接库.a:
[csy@local libtest] a r c r s v l i b a d d . a a d d . o / / . o l i b . a , l i b a d d . o l i b a d d . a : [ c s y @ l o c a l l i b t e s t ] ar -crsv libadd.a add.o //对目标文件*.o进行归档,生成lib*.a,此处lib要写 对目标文件add.o进行归档,生成libadd.a后文件列表: [csy@local libtest] ls
add.c add.o libadd.a main.c

静态库使用

方法一:当源文件使用
简单直接使用方法,把库存文件当成源文件使用:
gcc hello.c libadd.a -o haha

方法二:标准用法使用gcc 选项指定
在库文件的搜索路径中添加当前路径:
-ladd表示链接库文件libadd.a或libadd.so
-I./表示包含在当前目录中的头文件,如果代码没有使用到自定义的头文件不需要-I指定
[csy@local libtest]$ gcc -o main main.c -L./ -ladd -I.
[csy@local libtest]$ ls
add.c add.o libadd.a main main.c
[csy@local libtest]$ ./main
sum:110

sum:129

方法三:把.a存放在默认路径中,不需要指明库路径
[root@zhifachen libtest]#cp libadd.a /lib
/lib目录是编译器默认搜索库文件的路径之一,不需要指明这个路径它也能找到libadd
[root@zhifachen libtest]#gcc -o main hello.c -ladd
[root@zhifachen libtest]#./main

动态库存创建及使用

动态库(格式为libname.so[.主版本号.次版本号.发行号])。在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。

动态库创建

把上一个例子代码制作成动态库:
[csy@local libtest]$ gcc -fPIC -Wall -c add.c
[csy@local libtest]$ gcc -shared -o libadd.so add.o

也可以两步合成一步完成:
[csy@local libtest]$ gcc -fPIC -Wall -shared add.c -o libadd.so

动态库使用
  1. 使用动态库编译

  2. 方法一:当源文件使用
    简单直接使用方法,把库存文件当成源文件使用:
    [csy@local libtest]$ gcc hello.c libadd.so -o main
    方法二:标准方法,使用gcc选项指定库路径,库名
    [csy@local libtest]$ gcc -o main hello.c -L./ -ladd

  3. 测试可执行程序:将运行失败
    [csy@local libtest]$ ./main
    ./main: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
    测试失败,错误,提示找不到 libadd.so , 这就是动态库和静态库的一个区别。动态库链接不是把需要的代码复制到最终的可执行程序中,而是运行时候动态加载调用。所以还需要告诉系统在什么位置可以找到库,如何指定库路径在下面一小节中介绍。

注册动态库的路径.

  1. 方法1:将库文件拷贝到/lib或者/usr/lib下(系统默认搜索库路径)
    [csy@local libtest]$ cp libadd.so /lib
    [csy@local libtest]$ ./main
    sum:110
    ……
    sum:127
    sum:128
    sum:129
    [csy@local libtest]$

测试过程:

[root@local libtest]# ./main.exe 
./main.exe: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
[root@local libtest]# ls
add.c  add.o  libadd.a  libadd.so  main  main.c  main.exe
[root@local libtest]# cp libadd.so /lib/
[root@local libtest]# ./main
  1. 方法2:修改 LD_LIBRARY_PATH环境变量
    先删除方法复制的动态库文件:
    [csy@local libtest]$ rm /lib/libadd.so
    rm:是否删除普通文件 “/lib/libadd.so”?y
    运行,方便后面比较:
    [csy@local libtest]$ ./main
    ./main: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
    测试失败,找不到库。

学习export 命令:
export 是导出环境变量命令(环境变量名可以系统中预定义,也可以自定义)
[csy@local libtest]$ export Test_Export=123
[csy@local libtest]$ echo $Test_Export
123

上面的Test_Export是自定义的变量名,Linux系统中shell引用变量是 $变量名
注意:export 命令在终端中执行 时候,只在当前终端有效,新开的终端是无效的。

临时设置动态库环境变量:
设置系统预定义的环境变量 LD_LIBRARY_PATH ,这个变量值作用是告诉系统还可以到哪里去找动态库文件。
[csy@local libtest]$ export LD_LIBRARY_PATH= P W D [ c s y @ l o c a l l i b t e s t ] PWD [csy@local libtest] ./main
测试过程截图:
在这里插入图片描述
3. 方法3:修改 /etc/ld.so.conf
这个文件记录了动态链接库的路径。默认情况下,编译器只会使用 /lib和 /usr/lib这两个目录下的库文件。
把libadd.so所在路径添加到这个文件中后,再以 root 的身份运行ldconfig 命令才会生效。
为了测试这个方法,关闭前面打开的终端,因为方法2使用临时环境变量,但是只在当前终端有效。打开新终端,再次运行./main将失败,如下:

查看当前路径,后面要把这个路径添加到 /etc/ld.so.conf 文件中。
[csy@local libtest]$ pwd

[csy@local libtest]$ vim /etc/ld.so.conf
修改 /etc/ld.so.conf ,如下:
include ld.so.conf.d/*.conf
/root/work/test/libtest

修改好后,保存,运行./main测试:
[csy@local libtest]$ ./main
./main: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
还是会失败,因为还没有运行 ldconfig命令。
[csy@local libtest]$ ldconfig
[csy@local libtest]$ ./main
测试过程:
./main.exe: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory
[root@local libtest]# Idconfig
bash: Idconfig: command not found
[root@local libtest]# ldconfig
[root@local libtest]# ./main.exe
sum:110
sum:111

发布了65 篇原创文章 · 获赞 36 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_40860986/article/details/100183101