2013-05-01 68 views
7

我知道编译时包含在可执行文件中的代码可以来自对象文件(.o文件)和静态链接库(.lib/.a文件)。这两者之间的区别在根本上和概念上是什么?为什么“目标代码”和“静态链接库”有不同的概念?每个人有什么优点和缺点,为什么使用一个而不是另一个?静态链接库可以由目标文件创建,反之亦然,可以使用静态链接库创建目标文件?C/C++:静态链接库和目标文件有什么不同?

回答

6

库只是一个包含许多目标文件的文件,可以通过搜索来解析符号。因此,通常,当你将对象链接在一起时,你可以在一个可执行文件中获得所有对象(尽管一些优化链接器可以抛出未使用的对象)。

当您向链接器提供库时,它会检查其中的每个对象文件并引入满足未解决符号所需的那些对象文件(并且可能会继续将它们带入,直到所有符号都已解析或无更多可以)。

这只是将大量对象有效打包到单个文件中的一种方式,以便链接器可以完成更多的工作 - 您不必担心需要哪些对象。

如果您想到C库,您可能有一个printf.o,puts.o, fopen.o作为保持您的源很好地分开的结果。您不希望用户必须明确列出他们想要的每个对象文件,以便将所有内容打包到libc.a中,并告诉他们只需要链接该单个文件即可。


的静态链接位在这里无关紧要,它只是决定该对象应该进入链接时可执行文件,而不是在运行时被动态加载。这是解释here

+1

那么为什么在使用库文件而不是一个或多个目标文件时,用户必须执行的工作效率或工作量有什么不同?链接器不能总是优化吗?如果静态链接库是对象文件的集合,那么它是否将所有对象子文件全部加载或不加载,还是仅使用那些已被使用的符号?您是否有一个例子,说明如何根据代码是否来自静态链接库或目标文件,从相同的代码创建可执行文件,从而产生重大差异? – user553702 2013-05-01 07:02:35

+1

@ user553702,你想不得不列出85个不同的目标文件,其中有些文件甚至不需要,或者你想只列出'libc.a'并让链接器解决它?也许我天生懒惰,但这并不总是_bad_的事情:-)至于链接器如何工作,它可以抛弃那些即使明确列出它们也不会满足任何符号的东西。大多数人不会通过IST​​R Visual Studio那样聪明。 – paxdiablo 2013-05-01 07:05:11

+0

为简单起见,大多数链接程序仅从库中提取它们需要的目标文件(以及它们决定需要的每个目标文件的_all_)。 – paxdiablo 2013-05-01 07:07:38

9

目标文件是已编译但未链接的代码。库包含对象文件。因此你的问题就变成了:“如果我只能使用目标文件,为什么要使用静态链接的库?”这是为什么。

不同对象的集合,每个都有自己的符号表,库有单一的,统一符号表,当ar通过使用s开关库开发人员创建名为。 s调用ranlib为该存档中的所有对象创建统一的符号表。

运行壳ranlib显示帮助文本的第一行:

生成索引,以加快存取档案。

而且从通用ranlib docs

具有这种索引的存档可以加速链接库和 允许库中的程序,而不考虑叫对方 其放置在归档。T

另请参见FreeBSD ranlib docs - 不同的措词,相同的想法:联动的速度。