Linux 动态库和静态库详解
一、动静态库的基本原理
动静态库的本质是可执行程序的“半成品”,我们都知道,一堆源文件和头文件最终变成一个可执行程序需要经历以下四个步骤:
预处理: 完成头文件展开、去注释、宏替换、条件编译等,最终形成xxx.i文件。
编译: 完成词法分析、语法分析、语义分析、符号汇总等,检查无误后将代码翻译成汇编指令,最终形成xxx.s文件。
汇编: 将汇编指令转换成二进制指令,最终形成xxx.o文件。
链接: 将生成的各个xxx.o文件进行链接,最终形成可执行程序。
关于以上各类文件后缀的含义:
.o文件是目标文件,它是源代码编译后生成的二进制文件。.o是object的缩写,表示这个文件包含了目标代码,即机器语言代码。
.a文件是静态库文件,它是由多个目标文件打包而成的。.a是archive的缩写,表示这个文件是一个归档文件,包含了多个目标文件。
.so文件是动态库文件,它也是由多个目标文件组成的。.so是shared object的缩写,表示这个文件是一个共享对象,可以在程序运行时被载入。
.i文件是预处理后的C或C++源代码文件。预处理器会处理源代码中的宏定义、条件编译和头文件包含等指令,生成一个.i文件,其中包含了预处理后的源代码。
.s文件是汇编语言源代码文件。它包含了用汇编语言编写的程序代码,可以通过汇编器转换为机器语言代码。
.out文件是可执行文件,它包含了可以直接在计算机上运行的机器语言代码。.out是output的缩写,表示这个文件是编译器输出的结果。
.exe文件是Windows操作系统下的可执行文件。它包含了可以直接在Windows操作系统上运行的机器语言代码。.exe是executable的缩写,表示这个文件是可执行的。与.out文件类似,.exe文件也是编译器输出的结果,它可以直接在计算机上运行。不过,.exe文件只能在Windows操作系统上运行,而不能在其他操作系统(如Linux)上运行。
当有多个不同的源文件中的main函数调用这些功能函数时,每次都要重新对这几个函数重复预处理、编译、汇编操作,各自生成.o文件,然后再和调用功能函数的源文件(一般是main函数)生成的.o,最后才生成可执行程序。
这样会有很多重复的操作,所以一般将这些常用的函数所在的.cpp文件预处理、编译、汇编生成的多个.o文件打包在一起,称之为库。
二、核心概念
初步认识动静态库
#include<stdio.h>
int main()
{
printf("打印内容\n");
return 0;
}
在上面的代码中,我们就使用了c++的标准库,输出了一个内容,这个操作是通过gcc编译器在生成可执行程序时,将C标准库也链接进可执行程序中。
通过指令查看可执行程序依赖的库文件:
其中,libc.so.6就是这个可执行程序依赖的库文件,通过ll指令查看这个该路径下这个库文件的属性:

表明它其实是软链接到同目录下的libc-2.17.so文件,通过file指令,查看该文件的文件类型:
而上面的函数的库文件是 shared object,那么它是一种特殊的目标文件,可以在程序运行时被加载(链接)进来。在 Linux 下,动态链接库(shared object file,共享对象文件)的文件后缀为 .so。使用动态链接库的优点是:程序的可执行文件更小,便于程序的模块化以及更新,同时,有效内存的使用效率更高。
ldd 是一个命令,它用于打印程序或库文件所依赖的共享库列表。它不是一个可执行程序,而只是一个 shell 脚本。
动静态库的后缀因平台而不同:
- Linux :
.so:动态库;.a:静态库。- Windows :
.dll:动态库;.lib:静态库。
去掉前缀和后缀,剩下的就是库的名字。在这里,libc.so.6实际上是C语言的动态库,库名是c。
默认情况下,gcc/g++ 采用动态链接的方式链接第三方库。例如,当你指定 -lpng 时,链接程序就会去找 libpng.so。不过,gcc/g++ 提供了一个 -static 参数,可以改变默认链接方式。如:
gcc -static mylib.c -o mylib-s
三、制作与使用
演示:

1、先创建一个函数实现文件,一个头文件

2、通过( gcc -c 文件名 )指令,将.c文件转换成 .o 文件。链接生成可执行程序。

3、当我们想用这个静态库来连接的时候,发现操作系统找不到这个函数
更多推荐




所有评论(0)