2010-12-09 209 views

回答

5

它们实际上是相当不同的,特别是与旧的接头。

.o(或.obj)文件是目标文件,它们包含编译器生成代码的输出。它仍处于中间格式,例如,大多数参考文献仍未解决。通常在源文件和目标文件之间有一对一映射。

.a(或.lib)文件是档案,也称为库,是一组目标文件。

所有操作系统都有工具,允许您添加/删除/列出目标文件到库文件。

另一个区别,特别是对于较老的连接器,在连接文件时如何处理这些文件。有些链接会将完整的目标文件放入最终的二进制文件,而不管实际使用的是什么,而只会从库文件中提取有用的信息。

现在大多数链接器都足够聪明,可以删除所有未使用的东西。

+1

最后一句话很大程度上是错误的。 – 2010-12-09 14:41:40

9

从概念上讲,编译单元(源文件/目标文件中的代码单元)完全链接或根本不链接。虽然的某些实现在编译器和链接器之间具有显着的协作级别,但它们能够在链接时从目标文件中删除未使用的代码,但它不会更改在程序中包含具有冲突的符号名称的2个编译单元的问题一个错误。

作为一个实际的例子,假设你的函数库有两个函数foobar,它们在一个目标文件中。如果我想使用bar,但我的程序已经有一个名为foo的外部符号,那么我会遇到一个错误。即使该实现可能能够为我解决这个问题,该代码仍然不正确。另一方面,如果我有一个库文件包含两个单独的目标文件,一个使用foo,另一个使用bar,则只有包含bar的目标文件将被拉入我的程序。

编写库时,应避免在同一个对象文件中包含多个函数,除非它们必须一起使用。这样做会增加链接库(静态)的应用程序并增加符号冲突的可能性。就个人而言,如果存在疑问,我更喜欢在单独文件的一边犯错 - 如果后者不平凡,则将foo_createfoo_free放在单独的文件中甚至是有用的,以便不需要调用foo_free的短的一次性程序可以避免拉入用于深度释放的代码(并且甚至可能避免牵扯到free本身的实现)。

相关问题