将外部“C”放入C++代码中具体做什么?
例如:
extern "C" {
void foo();
}
将外部“C”放入C++代码中具体做什么?
例如:
extern "C" {
void foo();
}
当前回答
extern“C”是指由C++编译器识别,并通知编译器注意到的函数是(或将)以C样式编译的,因此在链接时,它链接到来自C的函数的正确版本。
其他回答
仅仅通过在外部“C”中包装,并不能使任何C标头与C++兼容。当C标头中的标识符与C++关键字冲突时,C++编译器会对此进行投诉。
例如,我看到以下代码在g++中失败:
extern "C" {
struct method {
int virtual;
};
}
Kinda是有道理的,但在将C代码移植到C++时需要记住。
当混合使用C和C++时(即a.从C++调用C函数;b.从C调用C++函数),C++名称混乱会导致链接问题。从技术上讲,只有当被调用函数已经使用相应的编译器编译成二进制(很可能是*.a库文件)时,才会出现此问题。
因此,我们需要使用外部“C”来禁用C++中的名称篡改。
在每个C++程序中,所有非静态函数都在二进制文件中表示为符号。这些符号是唯一标识程序中函数的特殊文本字符串。
在C中,符号名与函数名相同。这是可能的,因为在C中没有两个非静态函数可以具有相同的名称。
因为C++允许重载,并且具有许多C不具备的特性——比如类、成员函数、异常规范——所以不可能简单地使用函数名作为符号名。为了解决这个问题,C++使用了所谓的名称篡改,它将函数名和所有必要的信息(如参数的数量和大小)转换为一些只有编译器和链接器才能处理的奇怪字符串。
因此,如果将函数指定为extern C,编译器不会对其执行名称修改,而是可以直接使用其符号名作为函数名进行访问。
这在使用dlsym()和dlopen()调用此类函数时很方便。
这个答案是针对那些不耐烦/有最后期限的人的,下面只是部分/简单的解释:
在C++中,您可以通过重载在类中使用相同的名称(例如,由于它们都是相同的名称,因此无法从dll等导出)。解决这些问题的方法是将它们转换为不同的字符串(称为符号),符号说明了函数的名称,也说明了参数,因此即使这些函数具有相同的名称也可以唯一标识(也称为名称损坏)在C中,您没有重载,函数名是唯一的(因此,不需要单独的字符串来唯一标识函数名,因此符号是函数名本身)
所以在C++中,名称mangling唯一标识每个函数在C语言中,即使没有名字,也可以唯一地标识每个函数
要更改C++的行为,即指定不应对特定函数进行名称篡改,可以在函数名称之前使用外部“C”,无论出于何种原因,例如从dll导出具有特定名称的函数,供其客户端使用。
阅读其他答案,了解更详细/更正确的答案。
extern“C”是一个链接规范,用于调用Cpp源文件中的C函数。我们可以调用C函数、编写变量和包含头。函数在外部实体中声明,并在外部定义。语法为
类型1:
extern "language" function-prototype
类型2:
extern "language"
{
function-prototype
};
eg:
#include<iostream>
using namespace std;
extern "C"
{
#include<stdio.h> // Include C Header
int n; // Declare a Variable
void func(int,int); // Declare a function (function prototype)
}
int main()
{
func(int a, int b); // Calling function . . .
return 0;
}
// Function definition . . .
void func(int m, int n)
{
//
//
}