.o .a和.so文件有什么区别?

Utk*_*tav 24 c c++ shared-libraries static-libraries

我知道.o是目标文件,.a是静态库,.so是动态库吗?它们的物理意义是什么?我何时可以使用,何时不使用?

Cli*_*ord 45

.a是一个"档案".虽然存档可以包含任何类型的文件,但在GNU工具链的上下文中,它是一个目标文件库(其他工具链尤其是在WIndows上.lib用于相同目的,但这些工具的格式通常不是通用存档,并且通常特定于工具链).可以从存档中提取单个目标文件,这基本上是链接器在使用库时所执行的操作.

.o是一个目标文件.这是编译为机器代码但不(通常)完全链接的代码 - 它可能具有对通过单独编译生成的其他目标文件(在库中或单独)中定义的符号的未解析引用.对象文件包含支持与其他模块链接的元数据,也可以包含源级符号调试(例如,在GDB中).其他工具链,通常在Windows上,使用扩展.obj而不是.o.

.so 是一个共享对象库(或只是共享库).当程序启动时,它会动态链接到可执行文件,而不是在构建时静态链接.它允许较小的可执行文件,并且多个可执行文件使用单个对象库实例.操作系统API通常是共享库,并且它们也经常在GNU中用于许可,例如将LGPL代码与闭源专有代码分开(我不是律师 - 我没有对此方法的合法性提出任何要求.任何特殊情况).不同于.o.a文件,.so应用程序所使用的文件必须是可用的运行时系统.其他系统(通常也.dll称为Windows)使用(动态链接库)用于相同目的.

理解.o文件在文件中的目标代码之前链接可能是有用的,.a这样如果.o文件满足符号解析,则任何库实现都不会链接 - 允许您基本上用您自己的库实现替换库实现,也可以用于库调用用户定义代码的实现 - 例如GUI框架可能会调用应用程序入口点.


小智 8

静态库是包含库目标代码的档案,当链接到应用程序时,该代码被编译成可执行文件。

共享库的不同之处在于它们不会编译成可执行文件。相反,动态链接器搜索一些目录以寻找它需要的库,然后将其加载到内存中。多个可执行文件可以同时使用同一个共享库,从而减少内存使用和可执行文件大小。但是,还有更多文件要与可执行文件一起分发。您需要确保将库安装到用户系统上链接器可以找到它的某个位置,静态链接消除了这个问题,但会产生更大的可执行文件。

  • `但是,还有更多的文件要与可执行文件一起分发。` 理想情况下正好相反。例如 Linux 上的二进制包显然不会随身携带并尝试一遍又一遍地安装公共库的副本。它们标记了一个依赖项并强制用户安装它们。即使使用包管理器分发,人们通常也可以假设用户的系统已经拥有所需的库,或者用户可以获取它们。主要是 Windows 经常让事情变得如此困难,以至于我们放弃并重新分发所有 DLL。哪个,呃……有点违背了动态链接的意义 (2认同)

ros*_*031 5

.so 是共享库文件。.a 是静态库文件。

您可以静态链接到 .a 库,并在运行时动态链接和加载 .so 文件,前提是您以这种方式编译和链接。

.o 是目标文件(它们从 *.c 文件编译而来,可以链接以创建可执行文件、.a 或 .so 库。在此处了解更多信息