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

例如:

extern "C" {
   void foo();
}

当前回答

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

其他回答

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

您将经常看到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++中,您可以通过重载在类中使用相同的名称(例如,由于它们都是相同的名称,因此无法从dll等导出)。解决这些问题的方法是将它们转换为不同的字符串(称为符号),符号说明了函数的名称,也说明了参数,因此即使这些函数具有相同的名称也可以唯一标识(也称为名称损坏)在C中,您没有重载,函数名是唯一的(因此,不需要单独的字符串来唯一标识函数名,因此符号是函数名本身)

所以在C++中,名称mangling唯一标识每个函数在C语言中,即使没有名字,也可以唯一地标识每个函数

要更改C++的行为,即指定不应对特定函数进行名称篡改,可以在函数名称之前使用外部“C”,无论出于何种原因,例如从dll导出具有特定名称的函数,供其客户端使用。

阅读其他答案,了解更详细/更正确的答案。

仅仅通过在外部“C”中包装,并不能使任何C标头与C++兼容。当C标头中的标识符与C++关键字冲突时,C++编译器会对此进行投诉。

例如,我看到以下代码在g++中失败:

extern "C" {
struct method {
    int virtual;
};
}

Kinda是有道理的,但在将C代码移植到C++时需要记住。

在不与其他好答案冲突的情况下,我将添加一点我的示例。

C++编译器的作用是:它在编译过程中破坏了名称,因此我们需要告诉编译器要特别对待C实现。

当我们制作C++类并添加外部“C”时,我们告诉C++编译器我们正在使用C调用约定。

原因(我们从C++调用C实现):要么我们想从C++调用C++函数,要么从C调用C++函数(C++类…等在C中不起作用)。

请参阅下面的链接,该链接是Geeks for Geeks对外部“C”用法的解释。从下面的页面添加重要信息。

考虑函数f()的以下声明

int  f (void) { return 1; }
int  f (int)  { return 0; }
void g (void) { int i = f(), j = f(0); }

C++编译器可能会将上述名称更改为以下名称(来源:Wiki)

int  __f_v (void) { return 1; }
int  __f_i (int)  { return 0; }
void __g_v (void) { int i = __f_v(), j = __f_i(0); }

https://www.geeksforgeeks.org/extern-c-in-c/