C/C++静态库和动态库的制作、使用、优缺点

903 阅读4分钟

C++程序员必会的知识储备


什么是库???

  • 库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、类、函数等
  • 库是一种特殊的程序,编写库文件和编写一般的程序的区别不大,只是库文件不能单独运行
  • 库文件有两种,静态库和动态库(共享库) ,静态库在程序的链接阶段就被复制到了程序中,而动态库在链接阶段只是被记录的一些信息(如文件名),而没有把动态库复制到程序中,而是在程序运行阶段由系统动态加载到内存中供程序调用。
  • 库的好处:代码保密(c++程序即使被反编译也只能还原20%左右) 、方便部署和发布     

静态库的制作和使用

1).命名规则

lib + 库的名字 + .a [windows 下静态库以 .lib结尾]

2).制作步骤

  • 生成对应的 .o文件(.o为目标文件,即二进制文件,经过汇编器处理过的)   gcc  -c   *.c  -Iinclude
  • 将生成的.o文件打包(使用ar工具) ar rcs 库名(libXXX.a) *.o 

3).静态库的使用(头文件:提供了接口,方便调用库中的函数)

  • gcc main.c  lib/libXXX.a -o app -Iinclude
  • gcc main.c -L lib -l XXX -o app  -Iinclude

4).查看静态库里的东西     nm libXXX.a

5).查看可执行文件里的东西   nm app

动态库(共享库)的制作和使用

1).命名规则

lib + 库的名字 + .so [windows 下动态库以 .dll结尾]

2).制作步骤

  • 生成对应的.o文件(此时的.o文件要与位置无关)  gcc -fpic -c  *.c -Iinclude
  • 将.o文件打包成共享库   gcc -shared -o libXXX.so *.o -Iinclude

3).动态库的使用

  • gcc mian.o lib/libXXX.so -Iinclude -o app
  • gcc main.o -L ./lib -l XXX -o app -I ./include 

4).查询可执行文件在执行的时候所依赖的所有动态库   ldd 可执行文件

 

 libCalc.so  ==> not found   说明动态库libXXX.so没有找到

在运行是无法加载到  libCalc.so 

5).系统如何定位共享文件?

        当系统加载可执行代码的时候,能够知道其所依赖的库的名字,但是还需要知道文件的绝对路径。此时就需要系统的动态载入器来完成,对elf格式的可执行文件,是由ld-linux.so完成的。

 

 最后一行:ld-linux-x86-64.so

搜索elf文件的顺序:

DT_RPATH(我们改变不了) —>环境变量(path)LD_LIBRARY_PATH —> /etc/ld.so_cache文件列表

—>/lib/     /use/lib

如果找到库文件的绝对路径后,将其载入到内存中。

6).解决动态库链接失败的的原因(按道理有5种方法)

  • 改变DT_RPATH   改变不了,此法行不通
  • 改变环境变量(path)LD_LIBRARY_PATH
  1. 临时改变:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库目录的绝对路径                                                                                       /home/chen/MyWorkingSpace/library/lib
  2. 永久改变:在~/bashrc 文件中加入 这句话   然后更新  . .bashrc
  •  改变系统的 etc/profile文件中加入这句话
  • 修改/etc/ld.so.conf, 将动态库目录的绝对路径写入   然后更新 sudo ldconfig -v(打印详细信息) 

 动态库和静态库的工作原理

静态库:GCC进行链接时,会把静态库中的代码打包到可执行程序中

动态库:GCC进行链接时,动态库的代码不会被打包到可执行程序中(会记录一些信息,如名字)在程序启动之后,动态库会被动态加载到内存中。通过ldd(list dynamic dependcies)命令检查可执行文件动态库依赖关系

静态库的优缺点

静态库的优点

  • 方便移植:发布程序的时候,不需要提供对应的库,因为库已经打包到可执行文件中
  • 加载速度快(其实相比动态库快不了多少的)

静态库的缺点 

  • 消耗系统资源,浪费内存:库打包到应用程序中,导致库的体积很大
  • 库发生了改变(维护、升级),需要重新编译程序,导致更新、部署、发布麻烦

 动态库的优缺点

动态库的优点

  • 执行程序体积小
  • 动态库更新了,不重新编译程序(函数接口不变),更新、部署、发布简单
  • 可以控制何时加载动态库

动态库的缺点

  •  发布程序的时候,需要将动态库提供给用户
  • 动态库没有被打包到应用程序中,加载速度相对较慢

 动态库与静态库的选择

在库很小的时候,建议使用静态库。当库比较大的时候,尽量使用动态库。