Skip to content

Linux-动态链接库和静态链接库

https://www.zhihu.com/question/20484931

1. 为什么需要库?

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。 库从本质上说,就是一系列可执行代码的二进制形式,能够被操作系统载入内存执行。

  • 库的存在就是为了代码复用
  • 为什么不直接引用,比如头文件?
  • 一系列文件需要组织起来,便于调取
  • 比如LeetCode刷题需要用到的一系列头文件和cpp文件,需要将其编译成一个静态库,以便调用 image.png|350
  • 静态库:.a.lib
  • 动态库:.so, .dll

2. 程序编译的过程

shell
g++ -c hellospeak.cpp
  • 这段代码的-c,指示gcc,不仅需要执行链接,输出结果为对象文件,.o结尾的是对象文件。

shell
g++ hellospeak.cpp speak.cpp -o hellospeak
  • 这段代码将两个源码文件编译链接成一个单一的可执行程序
  • 如果没有-o参数,编译器采用默认的a.out

image.png|475

  • 静态库和动态库的区别在于,在链接这个环节,如何处理库,使之成为可执行程序,二者分别是动态链接方式和静态链接方式。

3. 静态库

  • 静态链接库可以看成一系列可执行的目标文件.o文件的集合。
  • 在链接阶段,将汇编生成的目标文件.o和用到的库一起链接打包到可执行文件当中
  • 静态库的特点如下
    • 静态库对于函数库的链接是放在编译时期完成的
    • 程序运行起来之后,和函数库就没有关系了,移植方便
    • 对于空间和时间都是浪费,因为所有目标相关的文件和函数库都要被链接成一个可执行文件

3.1 Linux下静态库的创建和使用

  • 必须形如lib[your_library_name].a前后的命名都是固定的
  • 创建流程
    • 可以手动创建
    • 也可以通过CMake创建,请参考CMake Demo
  • 如果多个不同的程序都用同一个静态库,比如2000个不同的程序,那么静态库就会复制2000份,内存开销也是2000倍。 image.png|450
  • 静态库的另外一个问题就是**发布更新非常困难,比如说静态库libTest.a更新了,那么所有使用它的应用程序必须编译。因为静态库对于函数库的链接是编译时完成的***,所以需要重新编译发布。比如一个游戏,上游静态库可能只是一个很小的变动,但是对于用户来说,需要完整下载整个游戏。

4. 动态库

  • 基于静态库的弱点,提出了动态库。
  • 动态库不参与程序编译的过程,只有在程序运行的时候才会被载入。
  • 如果不同的应用程序调用相同的库,内存当中只有一份库的实例
  • 对于软件发布来说,是可以增量更新image.png|450
  • 特点
    • 将库函数的载入放在了运行 阶段
    • 实现进程之间的资源共享
    • 让程序升级变得简单
    • 链接载入完全由程序员在程序代码当中控制(显示调用)