我的头文件有什么问题?

时间:2014-02-13 07:26:13

标签: c gcc compiler-errors

我刚刚完成了一项学校作业,我在测试代码时遇到了问题,因为我在运行make packetize后继续得到以下输出(这是教授给我们的makefile)

cc     packetize.c   -o packetize
/tmp/ccJJyqF6.o: In function `block_to_packet':
packetize.c:(.text+0xb1): undefined reference to `crc_message'
collect2: ld returned 1 exit status
make: *** [packetize] Error 1

block_to_packet在名为packetize.c的文件中定义,crc_messagecrc16.c中定义(两者都包含#include "data.h"行)。 data.h中还包含crc_message的函数标题所有这些文件都在同一目录中。在过去的一个半小时里,我一直在努力编译它们,并无休止地搜索谷歌无济于事。它与我读过的链接有关,我的导师没有教过这个,所以我不知道如何编译这些文件来测试他们的输出。任何人都可以让我知道什么是错的?

3 个答案:

答案 0 :(得分:4)

你的头文件绝对没问题。您所拥有的是链接器错误:packetize.c的编译运行没有问题,但是您尝试链接可执行文件文件{{1} (因为你没有给出packetize选项,说明“编译到对象文件”)。可执行文件也需要-c的编译代码。

您必须在编译器行上提供所有源:

crc16.c

或者你必须编译成单个目标文件,最终链接在一起:

cc packetize.c crc16.c -o myApp

前者是你在一次性命令行中所做的,后者是Makefile通常所做的。 (因为如果您所做的只是修改cc -c packetize.c -o packetize.o cc -c crc16.c -o crc16.o cc packetize.o crc16.o -o myApp ,则无需重新编译crc16.c。在大型项目中,重新编译可能需要花费大量时间。)

修改

教程时间。请注意给定命令行中是否存在packetize.c选项。

考虑:

-c

源文件定义函数// foo.c int foo() { return 42; }

foo()

头文件声明函数// foo.h int foo();

foo()

源文件引用 // main.c #include "foo.h" int main() { return foo(); }

在文件foo()中,include使编译器意识到最终在某处,main.c中声明了函数foo()的定义。此时所有编译器都需要知道函数将存在,它不带参数,并返回foo.h。这足以编译源到目标代码:

int

但是,实际编译可执行文件 <:>

cc -c main.c -o main.o

编译器承诺(通过声明)将存在cc main.c -o testproc # fail of compile-source-to-exe ld main.o -o testproc # fail of link-object-to-exe 的定义,这对于编译器而言足够

链接器但是(在第一个示例中由foo()隐式运行)需要该定义。可执行文件需要执行函数cc,但在foo()中找不到它。无法解析对main.c的引用。 “未解决的参考错误”。

您需要一次性编译两个源文件......

foo()

...或者编译cc foo.c main.c -o testproc # compile-source-to-exe 并为链接器提供两个目标文件,以便它可以解析所有引用:

foo.c

Post Scriptum :如上图所示,直接调用cc -c foo.c -o foo.o ld foo.o main.o -o testproc # link-objects-to-exe 很可能无法正常工作。链接需要一些额外的参数,ld隐式添加 - C运行时支持,标准C库,类似的东西。我没有在上面的例子中给出这些参数,因为它们会使问题混淆,超出了问题的范围。

答案 1 :(得分:0)

您还必须编译crc16.c并链接这两个目标文件以构建二进制文件。否则,调用crc_message()的packetize.c不知道它。

尝试使用

cc packetize.c crc16.c -o packetize

来自packetize.c的来电crc_message()就可以了。

答案 2 :(得分:0)

正如Totland所写,crc_message是在crc16.c中定义的;这意味着packetize.c无法看到定义,无论他们拥有多少共享头。您没有编译错误,但链接器出错。

如果首先将c文件编译为目标文件,然后将所有内容链接到可执行文件,它将起作用。