我们知道编译器大概可以分为6个阶段。预处理阶段、语法和语义分析阶段、代码生成阶段、优化阶段、汇编生成阶段、链接-载入阶段。而库文件,作用在链接阶段。
如果函数库的一份拷贝是可执行文件的物理组成部分,那么我们称之为静态链接;如果说可执行文件只是包含了文件名,让载入器在运行的时候能够寻找程序所需要的函数库,那么我们称之为动态链接。外部函数在真正被调用之前,运行时载入器并不解析他们,所以即使链接了函数库,如果没有实际的调用,就不会带来额外的开销。即使是在静态链接中,整个库文件也没有全部装入可执行文件中,所装入的只是需要的函数。
动态链接的最大的优点应该是可执行文件的体积可以非常的小。虽然运行速度会慢一些,但是却可以大幅度的利用磁盘空间。动态链接还有一个特别的优点:所有动态链接到某一个函数库的可执行文件运行的时候共享该函数库的同一份单独拷贝。如果是静态链接,则每一个文件都将拥有一份函数的拷贝。动态链接使得函数库的版本升级很容易更容易获得ABI的好处(应用程序二进制接口)。
通俗一点的说,就是静态链接方式就是链接的时候把库函数的代码类似于预处理的方式整合到整个代码中,然后生成了可执行文件。而动态链接方式只是对函数的所在地进行了记录,当使用到相应的函数的时候在去寻找相应的函数。动态链接方式的可执行文件本质上是没有库函数的具体的内容的,只是有去寻找该函数的具体的地址。自然的,包含库函数本身的静态链接的可执行文件,比只是包含库函数地址的动态链接的可执行文件,要大很多。
下面是一下linux中C函数库链接的注意的点:
- 动态文件的扩展名一般是".so",而静态库文件的扩展名一般是“.a”。当然扩展名在linux本身是不具备意义的,但是确实是一种标识。
2.你在编译的时候可以省略“lib”而只是用“l”, 你可以在编译时候通过 -lthread,告诉编译链接到libthread.so。 - 编译器要确定的目录找到库文件。
- 可以通过观察头文件来确定文件使用的库。