2

我了解创建 .c 和 .h 文件并将它们添加到我的项目时链接和编译的工作原理。

但是当我在我的项目中添加像 stdio.h 这样的标头时会发生什么?我了解链接器在某些标准目录中搜索 .h 文件,然后将其粘贴,但标头仅包含函数原型,没有代码。编译器或链接器在哪里找到这些函数的代码,以及它是如何添加到我的源文件中的?

我问的原因是因为我正在为微控制器编写引导加载程序,并且我想仔细查看所有实际发送到编译器的 C 代码。我正在为 PIC32 使用 XC32 编译器的非优化免费版本,所以我不相信它只包括我实际使用的内容。

4

2 回答 2

6

您需要区分标头和库。

标头声明程序可用的设施。当您包含诸如<stdio.h>(注意:这不是— 重复不是!— 库)之类的标头时,您可以向编译器提供使用标准 I/O 库中的设施所必需的信息。通常,C 头文件不定义实现这些设施的实际代码。C++ 具有“仅标头”库(Boost 的某些部分是“仅标头”库的主要示例)。

图书馆提供设施的实施。头<stdio.h>文件声明了一个函数fopen();某处有一个定义该功能的库。

一些头文件(实际上,通常是很多头文件)是特权的,它们声明的工具包含在 C 编译器链接您的程序的标准库中。您不必做任何特别的事情来将函数链接到您的程序中。其他头文件来自 C 编译器不知道先验的库,对于那些,你必须告诉它在哪里可以找到库(例如 with-L /opt/sometool/lib作为编译器选项)和库名称(例如 with -lsometool,它可能与/opt/sometool/lib/libsometool.so/opt/sometool/lib/libsometool.a)。请注意,SomeTool 的标头可能在 中/opt/sometool/include,您需要添加一个选项-I/opt/sometool/include来查找sometool.h标头。

链接器不引用标题;正确的编译器不引用库。编译器控制程序确实处理混合(它通常将编译过程的多个阶段作为单独的程序运行 - 编译器与链接器分开)。标头不包含有关库安装位置的信息。

于 2016-03-01T21:49:20.767 回答
4

链接器根本不关心头文件。链接器甚至不知道这些存在,因为它只看到已编译的目标文件,这就是为什么您需要明确指定要使用该-l...选项链接的库的原因。链接器在标准 C 库 ( -lc) 中隐式链接,这是找到标准 C 函数的方式。在许多平台上,这不适用于像sinor之类的数学函数pow,这就是为什么-lm当你想使用它们时需要链接的原因。

要回答在哪里-l...找到指定链接的库的问题:编译器有一组标准目录,它可以在其中查找。它也可能在工作目录中查找。您可以使用编译器选项将更多目录添加到库搜索路径。-L...这告诉链接器也在指定的目录中查找库。

于 2016-03-01T21:44:10.777 回答