考虑以下代码:

one.c:

#include <stdio.h>

int one() {
   printf("one!\n");
   return 1;
}

two.c:

#include <stdio.h>

int two() {
   printf("two!\n");
   return 2;
}

prog.c中

#include <stdio.h>

int one();
int two();

int main(int argc, char *argv[]) 
{
   one();
   two();

   return 0;
}

我想这些计划联系在一起。所以我这样做:

gcc -c -o one.o one.c
gcc -c -o two.o two.c
gcc -o a.out prog.c one.o two.o

此工作得很好。

或者我可以创建一个静态库:

ar rcs libone.a one.o
ar rcs libtwo.a two.o
gcc prog.c libone.a libtwo.a
gcc -L. prog.c -lone -ltwo

所以我的问题是:为什么我会使用第二个版本 - 而不是链接我的“的.o”文件 - 在我创建了一个名为“.a”文件中的一个?他们都似乎是静态链接,所以有在一个VS另一个优点或架构差异?

有帮助吗?

解决方案

通常库是可以在多个程序中使用的目标文件的集合。

在你的例子是没有任何优势的,但你可能会做的:

ar rcs liboneandtwo.a one.o two.o

然后将您的程序变得更简单:

gcc -L. prog.c -loneandtwo

这的确包装的问题。你有一组对象文件的自然形成一组相关的功能,可以在多个程序中重用?如果是这样,那么他们能够明智地归档到一个静态库,否则有可能是没有任何优势。

有在最终链接步骤一个重要的区别。你链接的任何对象文件都将被包含在最终的方案。这是在库的目标文件,如果他们帮助解决其他目标文件的任何未定义符号只包括在内。如果它们不匹配,就不会被链接到最后的可执行。

其他提示

的差异将在可执行文件的大小,虽然也许不是你的例子。

当链接到库中,仅由可执行文件中使用的比特被合并于此。当链接对象文件,你把整个事情。

举例来说,如果你的可执行文件必须包括在数学库中的每个数学函数的时候,你只能使用一个,这将是比它需要的是和含有大量的无用的代码要大得多。

有趣的是与Windows的动态链接模型来对比这一点。在那里,因此,操作系统加载所有的DLL(动态链接库),完全是你的可执行文件使用,这可能导致内存膨胀。这种模式的好处是,你的可执行文件本身较小,和链接的Dll可能已经通过其他可执行文件所使用的内存,所以他们并不需要重新加载。

在静态链接,库函数分别为每个可执行加载。

从技术上讲,结果是完全一样的。通常情况下,你创建的效用函数库,这样反而喂养几十个目标文件的链接,你只需要链接库。

顺便说一句,这绝对是没有意义的创建只包含一个.o文件将一个某文件。

您可以把文件的集合中的归档(.a)文件,以备后用。标准库是一个很好的例子。

有时是有意义的组织大项目到库。

的主要优点是,当你有链接,你可以指定一个库,而不是所有单独的目标文件。还有在管理文件,让对付一个库,而不是一堆目标文件的一小的优势。有一段时间,这也给了显著节省磁盘空间,但目前的硬盘价格做出那么重要了。

当有人问我这个问题(由新生在我的球队),“为什么(或有时甚至是‘什么是’)以.a?”,我用使用的.zip作为比喻下面的答案。

“A dotAy就像所有的dotOhs的zip文件,你会想同时建立你的EXE / lib目录链接。节省磁盘空间,加上一个不需要键入所有参与dotOhs的名字。”

到目前为止,这似乎让他们明白。 ;)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top