4

我正在使用 Linux,我有以下文件:

main.c, main.h
fileA.c, fileA.h
fileB.cpp, fileB.h

该函数F1()在 中声明fileB.h和定义fileB.cpp。我需要在 中使用该函数fileA.c,因此我将该函数声明为

extern void F1();

fileA.c.

但是,在编译过程中,我得到了错误

fileA.c: (.text+0x2b7): undefined reference to `F1'

怎么了?

谢谢你。

ETA:多亏了我收到的答案,我现在有了以下信息:

在fileA.h中,我有

#include fileB.h
#include main.h

#ifdef __cplusplus
extern "C" 
#endif
void F1();

在fileA.c中,我有

#include fileA.h

在fileB.h中,我有

extern "C" void F1();

在fileB.cpp中,我有

#include "fileB.h"

extern "C" void F1()
{ }

但是,我现在有错误

fileB.h: error: expected identifier or '(' before string constant
4

5 回答 5

17

如果您真的编译fileA.c为 C 而不是 C++,那么您需要确保该函数具有正确的、与 C 兼容的链接。

您可以使用extern关键字的特殊情况来执行此操作。在声明和定义中:

extern "C" void F1();
extern "C" void F1() {}

否则,C 链接器将寻找一个真正存在的函数,该函数仅具有一些损坏的 C++ 名称和不受支持的调用约定。:)

不幸的是,虽然这是您在 C++ 中必须做的,但语法在 C 中无效。您必须使extern仅对 C++ 代码可见。

因此,使用一些预处理器魔法:

#ifdef __cplusplus
extern "C"
#endif
void F1();

不完全漂亮,但这是您在两种语言的代码之间共享标头所付出的代价。

于 2011-06-21T09:56:29.317 回答
5

为了能够从 c 源代码调用 c++ 函数,您需要提供适当的linkage specification.

指定链接规范的格式是

extern "type_of_Linkage" <function_name>

所以在你的情况下,你应该使用:

extern "C" void F1();
于 2011-06-21T09:53:26.400 回答
4

也许,使用

extern "C" void F1();
于 2011-06-21T09:49:30.813 回答
2

fileA.c 不能包含 fileB.h(通过 fileA.h),因为 C 编译器不知道 extern "C" 是什么意思,所以它抱怨它在字符串之前看到了一个标识符。不要试图在 fileA.c 或 fileA.h 中包含 fileB.h。它不需要

于 2011-06-21T23:41:24.607 回答
-1

我相信 fileA.c 还需要包含 fileA.h。

于 2011-06-21T09:48:48.223 回答