【问题标题】:Including functions with extern C linkage in library在库中包含具有外部 C 链接的函数
【发布时间】:2023-04-10 01:15:02
【问题描述】:

我在 c++ 代码中包含了一些带有外部 c 链接的 C 函数。例如。

// File Y.cpp: 

extern C {  
 void fnA(void) { }  
 void fnB(void* a, void* b) { }  
}

class test {
....
};

// end of file

文件 Y 在模块 Mod 下。在为模块 Mod 构建库 libMod-O.a 时,我看不到包含 extern 块下的函数,除非 Y.h 包含在其他文件(Mod.cpp)中并且使用了类测试。因此,除非我在 Mod.cpp 中创建测试类的对象,否则我看不到 libMod-O.a 中的外部函数(fnA、fnB),即使在构建 libMod-O.a 期间编译了 Y.cpp。其结果是当另一个模块使用 fnA、fnB 时发生链接器错误。

我没有看到包含的外部函数 fnA 和 fnB 之间的联系以及 Mod.cpp 中类测试的使用。这是预期的还是有更好的方法来定义它?

【问题讨论】:

  • 最好将 extern C 声明移到 h 文件中。并在使用此外部函数的任何位置包含此 h 文件。
  • 当您说“我没有看到包含的功能”时,您的意思是您使用 objdump 或其他方法查看存档内容还是仅仅意味着您收到链接器错误?
  • 您可能会遇到链接顺序问题,其中使用 fnA 的文件位于 libMod-O.a 的链接之后,但带有对象测试的 Mod.cpp 位于 libMod-O.a 之前,因此 obj 文件在之前被拉入稍后需要 fnA/fnB。 gnu 链接器默认是单通道链接器。
  • 点击蒂亚戈建议的链接并找出答案。

标签: c++ c linker-errors extern


【解决方案1】:

你的意思当然是外部“C”。

您需要将 C 代码和 C++ 代码完全分开。

在 YourCCode.h 中:

#ifdef __cplusplus
extern "C" {
#endif

void fnA(void);
void fnB(void* a, void* b);

#ifdef __cplusplus
}
#endif

在 YourCCode.c 中:

void fnA(void) {}
void fnB(void* a, void* b) {}

确保您的编译器将 YourCCode.c 编译为 C,而不是 C++。

在您的 C++ 代码中

#include "YourCCode.h"

fnA();
// etc.

【讨论】:

    【解决方案2】:

    您可能会遇到链接顺序问题,其中使用 fnA 的文件位于 libMod-O.a 的链接之后,但带有对象测试的 Mod.cpp 位于 libMod-O.a 之前,因此需要在 fnA/fnB 之前拉入 obj 文件之后。 gnu 链接器默认是单通道链接器。

    【讨论】:

    • 我没有使用字符串或 objdump 来查看符号。我得到链接器错误。 libMod-O.a 也是 Mod.cpp 的库。 Y.cpp 和 Mod.cpp 都被编译成 libMod-O.a。否则,我不确定在 Mod.cpp 中创建测试对象如何解决问题。
    • 我刚刚运行了 strings 命令并在 libMod-O.a 中找到了 fnA 和 fnB。但是链接错误仍然发生,因为 Mod.cpp 中没有使用类测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    相关资源
    最近更新 更多