【问题标题】:Undefined Reference to a function未定义对函数的引用
【发布时间】:2011-09-19 09:10:42
【问题描述】:

我使用的是 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

【问题讨论】:

    标签: c++ c linux undefined-reference


    【解决方案1】:

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

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

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

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

    不幸的是,虽然这是您在 C++ 中必须做的事情,the syntax isn't valid in C。您必须使 extern 仅对 C++ 代码可见。

    所以,使用一些预处理器魔法:

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

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

    【讨论】:

    • 所以现在我有 extern "C" void F1();和 extern "C" void F1() {} 分别在我的 fileB.h 和 fileB.cpp 中,还有 extern "C" void F1();在文件 A.c.但在编译期间,我收到错误“fileB.h:错误:预期标识符或“(”字符串常量之前),“fileA.c:错误:预期标识符或“(”字符串常量之前),还有“fileA.c :警告:函数“F1”的隐式声明。”
    • @Tomalak:我仍然遇到一些错误。查看我对原始条目的编辑。
    • @Rayne:是__cplusplus,而不是__cpluplus。问题是:你的 C 可以看到函数声明两次。一个来自标题(您没有使用宏:这是 您应该这样做的地方,因为这是在语言之间共享的代码),另一个来自 fileA.c,其中你根本不应该写声明。
    • @Tomalak:我已经进行了更改(请参阅原始条目中的编辑),但仍然收到“预期标识符”错误。我不再有“隐式声明”错误了。
    • @Rayne: 为什么fileB.h 声明标题?您的 C 代码仍然可以看到一行 extern "C"。想想什么包括去哪里。您应该在one 头文件 中声明函数,并在one 源文件 中定义它。标头可以包含在很多地方,包括(感谢我们的宏技巧)在 C 源文件中。
    【解决方案2】:

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

    指定链接规范的格式是

    extern "type_of_Linkage" <function_name>
    

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

    extern "C" void F1();
    

    【讨论】:

      【解决方案3】:

      也许,使用

      extern "C" void F1();
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 包含失败在编译时给出声明错误,而不是在链接时出现定义错误。
          猜你喜欢
          • 2019-09-05
          • 2017-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-09
          • 2012-10-07
          • 2015-10-02
          • 2012-10-14
          相关资源
          最近更新 更多