extern主要用于告诉编译器,其申明的变量、函数可以在本模块或其他模块使用,其和关键字static相对应。
被extern “C”修饰的变量和函数按照C语言方式编译和链接的。
-
应用场景
当C++代码需要调用已有的C代码时,则在C代码的函数申明前加上extern “C”即可。这样C++代码可以直接调用C代码变量、函数接口了,不必对原有C代码的实现进行修改。 -
原因
C代码和C++代码编译规则存在差异。由于C++支持重载,编译后的函数符号以函数名和形参类型命名,而C编译后的函数符号仅以函数名命名。如函数void func(int, int),在C++编译环境下编译后的函数名为_func_int_int(不同编译器可能存在差异,但基本类似),C编译环境下编译后的函数名可能为_func。
假设C++模块代码B需要调用C模块代码A中实现的函数void func(int, int)。若A模块接口不采用extern "C"申明。首先在各自完成了编译过程后,B在链接过程中会从A生成的目标文件中查找符号_func_int_int。显然这是不可能找到的,因为A模块将对应函数编译生成的符号为_func,导致最终链接失败。
结合常见标准头文件代码结构说明如下:
#ifndef _CSDN_H_ /* 防止头文件重复包含 */
#define _CSDN_H_
/* 该部分告诉编译器,如果定义了__cplusplus宏(如果是c++的cpp默认定义了宏__cplusplus),则按照C语言方式进行编译、链接 */
#ifdef __cplusplus
extern "C"{
#endif
/* 相关变量、函数申明 */
#ifdef __cplusplus
}
#endif
#endif