什么是库?

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库和动态库,动态库原名就是shared objects,windows上对应的是 .lib .dll,linux 上对应的是 .a .so。

image.png

库的概念是在链接阶段出现的,接下来我们开始区分静态库和动态库

静态库和动态库

静态库在链接阶段,会将汇编生成的目标文件 .o 与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接,静态库对函数库的链接是放在编译过程(上面的四个总过程)完成的。静态库在一个程序中做到了代码复用的作用。

image.png

静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新),多开软件也会重复加载静态库。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。

头文件和库

头文件 stdio.h 里只有函数原型,里面的函数就定义在库中,库文件都是二进制形式的是已经被编译。

编译器干什么

标准库函数不是由编译器实现的,编译器的作用就是“编译”,不提供函数实现。头文件、链接库等,是由标准库或第三方软件包提供的(通常就是我们下载的一系列 toolchain )。

总之编译器就是把程序员写的源码转换为目标码,标准库则是提供给程序员现成的函数实现和宏,这些方法被封装在动态链接库或静态链接库或直接在头文件里,然后由头文件声明供程序员使用。