对象文件和共享对象文件之间的关系(Relation between object file and

2019-07-31 04:22发布

什么是共享对象(关系.so )文件和对象( .o )文件?

你能请通过例子来解释?

Answer 1:

比方说,你有以下的C源文件,称它为name.c

#include <stdio.h>
#include <stdlib.h>

void print_name(const char * name)
{
    printf("My name is %s\n", name);
}

当你编译它,与cc name.c你产生name.o 。 该的.o包含实际的代码相关联的他们的名字在name.c定义的所有函数和变量编译后的代码和数据,以及指标。 如果你看的是指数,与说的nm工具(在Linux和许多其他的Unix可用),你会发现两个条目:

00000000 T print_name
         U printf

这意味着:有存储在的.o两个符号(函数或变量的名称,但不是类,结构,或任何类型的名称)。 首先,标有T实际上包含其定义 name.o 。 另一方面,标有U仅仅是一个参考 。 对于代码print_name可以在这里找到,但对于代码printf不能。 当你的实际程序运行它将需要找出所有引用的符号,并期待它们的定义在其它目标文件才能被链接成一个完整的程序或完整的图书馆。 因此,目的文件是源文件中找到的定义,转换成二进制形式,并且可用于放置成一个完整的程序。

您可以链接在一起.o文件一个接一个,但你不知道:一般有很多人,他们是一个实现细节。 你真的愿意把它们都收集到相关对象束,具有公认的名称。 这些包称为 ,它们有两种形式:静态和动态。

静态库 (在UNIX中)几乎总是用后缀.a (实例包括libc.a这是C核心库, libm.a其是C数学库)等。 继续你与你建立的静态库的例子ar rc libname.a name.o 。 如果您运行nmlibname.a你会看到这一点:

name.o:
00000000 T print_name
         U printf

正如你可以看到它主要是目标文件与索引发现它所有的名字一大桌。 就像对象文件它同时包含在每一个定义的符号.o和他们提及的符号。 如果你在其他的.o(如链接date.oprint_date ),你会看到类似上面的另一个入口。

如果你在一个静态库链接到可执行它嵌入整个库到可执行文件。 这就像在所有单个链接.o文件。 你可以想像这可以使你的程序非常大,特别是如果你正在使用(如最先进的应用程序)很多图书馆。

动态共享库后缀.so 。 它,喜欢它的静态模拟,是目标文件的一张大桌子,指的是编译的所有代码。 你会先建立它cc -shared libname.so name.o 。 与望着nm比虽然静态库有点不同。 在我的系统它包含了两打只有两个是符号print_nameprintf

00001498 a _DYNAMIC
00001574 a _GLOBAL_OFFSET_TABLE_
         w _Jv_RegisterClasses
00001488 d __CTOR_END__
00001484 d __CTOR_LIST__
00001490 d __DTOR_END__
0000148c d __DTOR_LIST__
00000480 r __FRAME_END__
00001494 d __JCR_END__
00001494 d __JCR_LIST__
00001590 A __bss_start
         w __cxa_finalize@@GLIBC_2.1.3
00000420 t __do_global_ctors_aux
00000360 t __do_global_dtors_aux
00001588 d __dso_handle
         w __gmon_start__
000003f7 t __i686.get_pc_thunk.bx
00001590 A _edata
00001594 A _end
00000454 T _fini
000002f8 T _init
00001590 b completed.5843
000003c0 t frame_dummy
0000158c d p.5841
000003fc T print_name
         U printf@@GLIBC_2.0

共享库从静态库的区别一个非常重要的方式:它不会自己嵌入在最终的可执行文件。 取而代之的是可执行文件中包含该解决,而不是在链接时该共享库的引用,但在运行时。 这有很多的优点:

  • 你的可执行文件要小得多。 它仅包含您通过目标文件明确链接的代码。 外部库是引用文件,其代码不会进入二进制文件。
  • 您可以共享(因此得名),一个库的多个可执行文件中的位。
  • 你可以,如果你小心的二进制兼容性,更新程序的运行之间的库中的代码,并计划将搭载全新的图书馆没有你需要去改变它。

也有一些缺点:

  • 这需要时间来计划联系在一起。 随着共享库的一些这段时间被推迟到每一个可执行文件运行时。
  • 这个过程是比较复杂的。 所有的共享库的附加符号,使在运行时库连接起来所需要的基础设施的一部分。
  • 您运行细微的不兼容的不同库的版本之间的风险。 在Windows中,这个被称为“DLL地狱”。

(如果你想想看很多这些都是原因程序使用或不使用引用和指针,而不是直接嵌入一个类的对象到其他对象。这个比喻是很直接的。)

好吧,这是一个很多细节,我已经跳过了很多,比如连接过程实际上是如何工作的。 我希望你能理解。 如果不要求澄清。



Answer 2:

一个.so类似于在Windows中的.dll。 的.o是完全一样的Visual Studio下的obj。



文章来源: Relation between object file and shared object file