【问题标题】:C and C++ linkage with extern "C"C 和 C++ 与 extern "C" 的链接
【发布时间】:2012-07-20 14:02:50
【问题描述】:

我在 .h 文件中定义了一个 C++ 函数,如下所示,并在 .cpp 文件中实现:

extern "C" void func(bool first, float min, float* state[6], float* err[6][6])
{
    //uses vectors and classes and other C++ constructs
}

如何在 C 文件中调用 func?如何设置我的文件架构/makefile 来编译它?

谢谢!

【问题讨论】:

  • 函数是在头文件中定义(即包括{ }之间的部分),还是在头文件中声明(即, 以);) 结尾?如果是前者,则需要编写另一个头文件,省略 extern "C"{ } 部分,并将 that 用于程序的 C 部分。
  • 我认为我的问题解释得不够清楚。我会尝试更好的例子。
  • 我要删除并重新发布

标签: c++ c extern linkage


【解决方案1】:

您以正常方式从 C 中调用函数。但是,您需要将 extern "C" 包装在预处理器宏中以防止 C 编译器看到它:

#ifndef __cplusplus
extern "C"
#endif
void func(bool first, float min, float* state[6], float* err[6][6]);

假设您正在使用 GCC,然后使用 gcc 编译 C 代码,使用 g++ 编译 C++ 代码,然后使用 g++ 链接。

【讨论】:

  • 我从 gcc 得到错误,说不能包含向量,因为我的 C 文件包含定义 func 的文件,该文件使用向量
  • 你可能只想用 g++ 编译整个东西?当您构建 .dll 并希望链接到它而不必知道损坏的名称时,我通常会在 C++ 代码中看到 extern "C"。
  • @CodeKingPlusPlus:也看看我的答案底部。
  • @CodeKingPlusPlus:“链接是什么意思?” - 我担心我们这里有问题...查看 GCC 手册中的-c 选项,以及“链接”是关于什么的。否则,您在这里得到的任何答案都是没有意义的。
  • @JoshPetitt:在这种情况下,任何类型的共享库(.so.dll 等)。因为这是GCC,所以我认为可能是Linux,如果不是,其他平台的GCC仍然使用.so。 (Mac 无论如何都会使用它,在 Windows 上你需要一个类似 Cygwin 的层)。
【解决方案2】:

要在 C 中调用它,您需要做的就是正常调用它。因为您告诉编译器使用 C 调用约定和带有 extern "C" 的 ABI,所以您可以正常调用它:

func(args);

对于编译器,将其用于 C++:

g++ -c -o myfunc.o myfunc.cpp

那么这个对于C:

gcc -c -o main.o somec.c

比链接:

g++ -o main main.o myfunc.o

确保函数的 C++ 标头使用ONLY C CONSTRUCTS。因此,请在 .cpp 文件中包含 <vector> 之类的内容。

【讨论】:

  • @CodeKingPlusPlus:-c 选项告诉编译器仅将您的代码编译为中间目标代码文件 (.o),然后可以通过排除 -c 选项将其链接到可执行文件中.目标文件允许您组合 C 和 C++,并在项目的不同部分中进行一些分离。它们还允许您只编译代码的一小部分,这对于像 make 这样的大型项目和系统至关重要。
  • 谢谢!当我运行最后一个编译行(gcc -o main main.o myfunc.o)时,它失败并告诉我我对 myfunc.cpp 中包含的文件有未定义的引用
  • @CodeKingPlusPlus:到什么文件? 确切的消息是什么?
【解决方案3】:

用 C 调用它

func(/* put arguments here */);

通过说 extern "C" 你是在要求编译器不要破坏你的名字。否则,C++ 编译器会倾向于在链接器之前破坏它们(即添加额外的符号以使其唯一)。

您还需要确保已设置为使用 C 调用约定。

【讨论】:

【解决方案4】:
//header file included from both C and C++ files

#ifndef __cplusplus
#include <stdbool.h> // for C99 type bool
#endif

#ifdef __cplusplus
extern "C" {
#endif

void func(bool first, float min, float* state[6], float* err[6][6]);

#ifdef __cplusplus
} // extern "C"
#endif

// cpp file
#include "the_above_header.h"
#include <vector>

extern "C" void func(bool first, float min, float* state[6], float* err[6][6]);
{
    //uses vectors and classes and other C++ constructs
}

// c file
#include "the_above_header.h"

int main() {
    bool b;
    float f;
    float *s[6];
    float *err[6][6];
    func(b,f,s,err);
}

【讨论】:

    猜你喜欢
    • 2019-12-22
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    相关资源
    最近更新 更多