标签:com 说明 ios 很多 总结 return main 有用 代码块
一、引言
extern "C"{};的作用就是为了实现C++代码调用其他C语言代码。加上extern "C"后,会告知编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数时,会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;但C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
这个功能十分有用,因为在C++出现以前,很多代码都是C语言写的,而且很底层的库也是C语言写的,为了更好的支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略。
二、举例
一共3个文件,分别是用C语言实现的加法运算函数cPlus.h和cPlus.c,以及用C++实现的主函数main.cpp
// cPlus.h
int addC(int x, int y);
// cPlus.c
#include "stdio.h"
int addC(int x, int y)
{
return x + y;
}
主函数:
// main.cpp
#include "cPlus.h"
#include "iostream"
using namespace std;
int main()
{
cout << addC(2, 3) << endl;
return 0;
}
可以看到主函数main是用C++实现的,并且在主函数中调用了用C语言实现的加法函数addC。
接下来进行编译,报错了,报错信息如下,无法解析符号addC(int, int):
重新改写cPlus.h文件如下:
// cPlus.h
#ifdef __cplusplus
extern "C" {
#endif
int addC(int x, int y);
#ifdef __cplusplus
};
#endif
再次对main函数进行编译,发现编译成功。
三、分析
为什么对C代码块增加了extern "C"{};之后,编译就不会报错了?这还是得从C语言和C++本身说起。
C和C++编译器对变量或函数的编译处理是不完全相同的。C++支持重载,编译后的函数一般是以下划线+函数名+形参类型来命名的;C语言不支持重载,编译后的变量或函数一般以下划线+函数名来命名的。
如函数void fun(int,int),C++编译后的可能是_fun_int_int(不同编译器可能不同);而C语言编译后可能是_fun。
因此,main函数里用C++对addC进行编译得到_addC_int_int的函数名,而C代码里自身对addC进行编译得到的是_addC的函数名,这就会造成在链接过程中C++在符号库里会找不到_addC_int_int这个符号表。但是在C代码里用extern "C"进行说明后,用C++对addC进行编译时,会按照C语言格式进行编译,生成_addC函数名。
打开一个C语言的标准头文件如stdio.h后,可以发现,都是有类似的结构:
// stdio.h
#ifndef _INC_STDIO
#define _INC_STDIO
#ifdef __cplusplus
extern "C" {
#endif
code...
#ifdef __cplusplus
}
#endif
四、使用场景
1、C++代码调用C语言代码。
2、在C++的头文件中使用。
3、在多个人协同开发时,有的人擅长C语言,有的人擅长C++,这种情况下也会用到。
五、用法总结
1、可以单一语句使用
extern "C" int addC(int, int);
2、可以复合语句使用
extern "C" {
int addC(int, int);
}
3、可以包含头文件,相当于头文件中的声明都加了extern "C"
extern "C" {
#include "stdio.h"
int addC(int, int);
}
4、不可以将extern "C"添加在函数内部,例如下面的用法是错的
int addC(int x, int y)
{
extern "C" {
return x + y;
}
}
六、注意
1、extern "C"用来指明,这段代码按照C语言方式进行编译。
2、extern "C"是用来修饰C代码的,使用目标是C代码,不存在在C++代码里使用。
3、extern本身也是C语言的一个关键字,其修饰的变量或函数可以在本模块或其它模块中使用,因此extern "C"修饰的变量或函数具有和extern相同的生命周期。
4、由于static和extern的作用正好相反,因此用static修饰的函数或变量不能被extern "C"修饰。
5、extern "C"一般配合着__cplusplus使用。__cplusplus是告诉编译器,如果定义了__cplusplus,即如果是cpp文件,因为cpp文件都是默认会定义这个宏的。
[C/C++知识点] C++调用C语言之extern "C"
标签:com 说明 ios 很多 总结 return main 有用 代码块
原文地址:https://www.cnblogs.com/programmer-home/p/13672429.html