C 我的头文件有什么问题?

C 我的头文件有什么问题?,c,gcc,compiler-errors,C,Gcc,Compiler Errors,我刚刚完成了一项学校作业,在测试代码时遇到了问题,因为在运行makepacketize之后,我一直得到以下输出(这是教授给我们的makefile) 块到数据包在名为packetize.c的文件中定义,crc\u消息在crc16.c中定义(两者都包含包含“data.h”行)data.h中还有一个函数标题,用于crc\u message在其中,所有这些文件都在同一目录中。在过去的一个半小时里,我一直在试图编译它们,但一直在谷歌上搜索,没有结果。这和我读过的链接有关,我的导师没有教过,所以我不知道如何

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


块到数据包
在名为
packetize.c
的文件中定义,
crc\u消息
crc16.c
中定义(两者都包含
包含“data.h”
行)
data.h
中还有一个函数标题,用于
crc\u message
在其中,所有这些文件都在同一目录中。在过去的一个半小时里,我一直在试图编译它们,但一直在谷歌上搜索,没有结果。这和我读过的链接有关,我的导师没有教过,所以我不知道如何编译这些文件来测试它们的输出。有人能告诉我出了什么事吗

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

试用

cc packetize.c crc16.c-o packetize


从packetize.c调用crc_message()就可以了。

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

试用

cc packetize.c crc16.c-o packetize


您从packetize.c调用crc_message()就可以了。

您的头文件绝对正常。您遇到的是一个链接器错误:
packetize.c
的编译没有出现问题,但是您正在尝试链接一个可执行文件
packetize
(因为您没有提供声明“编译到对象文件”的
-c
选项)。可执行文件还需要来自
crc16.c
的编译代码

您必须在编译器行中提供所有源代码:

cc packetize.c crc16.c -o myApp
或者您必须编译成单独的对象文件,最终链接在一起:

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

编辑:

辅导时间。注意给定命令行中是否存在
-c
选项

考虑:

// foo.c

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

声明函数
foo()
的头文件

引用
foo()
的源文件

在文件
main.c
中,include使编译器意识到,最终在某个地方,会有
foo.h
中声明的函数
foo()
的定义。此时,编译器需要知道的是函数将存在,它不带任何参数,并且返回
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
,并向链接器提供两个对象文件,以便它能够解析所有引用:

cc -c foo.c -o foo.o
ld foo.o main.o -o testproc    # link-objects-to-exe

Post Scriptum:如上图所示直接调用
ld
,很可能不会像那样工作。链接需要两个额外的参数,
cc
隐式地添加这些参数——C运行时支持、标准C库等等。我没有在上面的示例中给出这些参数,因为它们会混淆问题,并且超出了问题的范围。

您的头文件绝对正确。您遇到的是一个链接器错误:
packetize.c
的编译没有出现问题,但是您正在尝试链接一个可执行文件
packetize
(因为您没有提供声明“编译到对象文件”的
-c
选项)。可执行文件还需要来自
crc16.c
的编译代码

您必须在编译器行中提供所有源代码:

cc packetize.c crc16.c -o myApp
或者您必须编译成单独的对象文件,最终链接在一起:

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

编辑:

辅导时间。注意给定命令行中是否存在
-c
选项

考虑:

// foo.c

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

声明函数
foo()
的头文件

引用
foo()
的源文件

在文件
main.c
中,include使编译器意识到,最终在某个地方,会有
foo.h
中声明的函数
foo()
的定义。此时,编译器需要知道的是函数将存在,它不带任何参数,并且返回
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
编译器(通过声明)承诺