Linux C编程(四) 之 静态库和动态库

概述

linux下有两种库:动态库和静态库 二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。
静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
静态库在程序编译时会被复制到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被复制到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在

  1. 静态库的编写和使用

     命名规则:lib库名.a
    
    1. 将所有要加入静态库的模块编译为目标文件.

       juggler@ubuntu:~/uc/day03/t_math$ ls
       add.c  main.c  mul.c  p_math.h
       juggler@ubuntu:~/uc/day03/t_math$ gcc -c add.c mul.c tarena@ubuntu:~/uc/day03/t_math$ ls
       add.c  add.o  main.c  mul.c  mul.o  p_math.h
      
    2. 将第一步生成的目标文件打包到静态库文件中

       juggler@ubuntu:~/uc/day03/t_math$ ar -r libpmath.a *.o
       ar: 正在创建 libpmath.a
       juggler@ubuntu:~/uc/day03/t_math$ ls 
       add.c  libpmath.a  mul.c  p_math.h
       add.o  main.c      mul.o
      
    3. 使用静态库文件链接生成可执行文件

       juggler@ubuntu:~/uc/day03/t_math$ gcc -c main.c 
       juggler@ubuntu:~/uc/day03/t_math$ gcc main.o -L. -lpmath
       juggler@ubuntu:~/uc/day03/t_math$ ls
       add.c  a.out       main.c  mul.c  p_math.h
       add.o  libpmath.a  main.o  mul.o
       juggler@ubuntu:~/uc/day03/t_math$ ./a.out 
       6+2=8
       -L路径    链接器寻找库文件的路径
       -l库名    指定要找的库的名字
       -I 路径   预处理时寻找头文件的路径
      
  • 在UNIX中,使用ar命令创建或者操作静态库

      ar archivefile objfile
      
      archivefile:archivefile是静态库的名称
      
      objfile:objfile是已.o为扩展名的中间目标文件名,可以多个并列
      
      参数 意义
      
      -r 将objfile文件插入静态库尾或者替换静态库中同名文件
      
      -x 从静态库文件中抽取文件objfile
      
      -t 打印静态库的成员文件列表
      
      -d 从静态库中删除文件objfile
      
      -s 重置静态库文件索引
      
      -v 创建文件冗余信息
      
      -c 创建静态库文件
    
  1. 动态链接
    1. 动态链接库的制作和使用

       * 命名规则 lib库名.so
      
    2. 将要加入动态库的源文件编译为目标文件(与位置无关的目标文件)

       t_math$ls
       add.c  main.c  mul.c  p_math.h
       t_math$gcc -c -fPIC add.c mul.c 
       t_math$ls
       add.c  add.o  main.c  mul.c  mul.o  p_math.h
      
       -fPIC:生成与位置无关的目标文件
      
    3. 将第一步生成的目标文件打包到动态库文件中

       t_math$gcc -shared -o libpmath.so *.o
       t_math$ls 
       add.c  libpmath.so  mul.c  p_math.h
       add.o  main.c       mul.o
      
    4. 使用动态库链接生成可执行文件

       t_math$gcc main.c -L. -lpmath
       t_math$ls
       add.c  a.out        main.c  mul.o
       add.o  libpmath.so  mul.c   p_math.h
       
       t_math$a.out 
       a.out: error while loading shared libraries: libpmath.so: cannot open shared object file: No such file or directory
      
    5. 使用静态库链接生成的可执行文件.从静态库中找到程序中使用的模块,将这些模块合并到可执行文件中.可执行文件是独立的文件.不再依赖静态库文件.

    6. 使用动态库生成的可执行文件.和动态库是两个独立的模块.这种可执行文件要执行的时候,必须将可执行文件和动态库一起加载到内存.

    7. 需要指到可执行文件依赖哪些动态库文件?
      ldd a.out

    8. 告诉动态链接器到哪里去找动态库文件.
      两种方法解决

      1. 使用LD_LIBRARY_PATH环境变量告诉动态链接器

         export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
        
      2. 链接器默认的搜索路径是/lib或者/usr/lib

         mv libpmath.so /lib
         mv libpmath.so /usr/lib
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值