将外部“C”放入C++代码中具体做什么?

例如:

extern "C" {
   void foo();
}

当前回答

我只是想添加一些信息,因为我还没有看到它发布。

您将经常看到C头中的代码,如下所示:

#ifdef __cplusplus
extern "C" {
#endif

// all of your legacy C code here

#ifdef __cplusplus
}
#endif

这实现的是,它允许您在C++代码中使用C头文件,因为宏__cplusplus将被定义。但是您也可以将它与遗留的C代码一起使用,因为宏没有定义,所以它不会看到唯一的C++构造。

虽然,我也见过C++代码,例如:

extern "C" {
#include "legacy_C_header.h"
}

我想这也能完成同样的事情。

不知道哪种方式更好,但我都见过。

其他回答

它通知C++编译器在链接时以C样式查找这些函数的名称,因为在链接阶段,用C和C++编译的函数的名称不同。

extern“C”是指由C++编译器识别,并通知编译器注意到的函数是(或将)以C样式编译的,因此在链接时,它链接到来自C的函数的正确版本。

在每个C++程序中,所有非静态函数都在二进制文件中表示为符号。这些符号是唯一标识程序中函数的特殊文本字符串。

在C中,符号名与函数名相同。这是可能的,因为在C中没有两个非静态函数可以具有相同的名称。

因为C++允许重载,并且具有许多C不具备的特性——比如类、成员函数、异常规范——所以不可能简单地使用函数名作为符号名。为了解决这个问题,C++使用了所谓的名称篡改,它将函数名和所有必要的信息(如参数的数量和大小)转换为一些只有编译器和链接器才能处理的奇怪字符串。

因此,如果将函数指定为extern C,编译器不会对其执行名称修改,而是可以直接使用其符号名作为函数名进行访问。

这在使用dlsym()和dlopen()调用此类函数时很方便。

当混合使用C和C++时(即a.从C++调用C函数;b.从C调用C++函数),C++名称混乱会导致链接问题。从技术上讲,只有当被调用函数已经使用相应的编译器编译成二进制(很可能是*.a库文件)时,才会出现此问题。

因此,我们需要使用外部“C”来禁用C++中的名称篡改。

它以这样一种方式更改函数的链接,即该函数可以从C调用。实际上,这意味着函数名不会被破坏。