一、概述
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。extern "C"表明了一种编译规约,其中extern是关键字属性,“C”表征了编译器链接规范。对于extern "C"可以理解成在C++/C中的混合编程的编译指令。
一般使用方法如下
#ifdef __cplusplus /* 如果采用了C++,如下代码使用C编译器 */
extern "C" { /* 如果没有采用C++,顺序预编译 */
#endif
/* 采用C编译器编译的C语言代码段 */
#ifdef __cplusplus /* 结束使用C编译器 */
}
#endif
二、编译方式
C++是面向对象的语言,支持重载,而C是过程式语言不支持,两者函数被C++编译后在符号库中的名字与C语言的不同。
例如: void func(int x, int y)
C编译器生成:_func
C++编译器生成类似: _func_int_int(不同类型编译器可能不同),名字包含了函数名、参数、类型信息,C++就是靠这些参数实现重载:
void func(int x, int y) ------> _fuc_int_int
void func(int x, float y) ------> _fuc_int_float
三、习惯用法
1、包含include头文件
file.c
extern "C"
{
#include "file1.h"
#include "file2.h"
}
2、使用C的方式处理
#ifdef _cplusplus
extern "C" :
#endif
代码
代码
#ifdef _cplusplus
}
#endif
举例说明:
c和c++头文件实现文件各一个
/*test_c.h*/
#ifndef TEST_C
#define TEST_C
int add(int a, int b);
#endif
/*test_c.c*/
#include "test_c.h"
int add(int a, int b)
{
int c;
c = a + b;
return c;
}
/*test_c++.h*/
#ifndef TEST_C_PLUSPLUS
#define TEST_C_PLUSPLUS
int substract(int a, int b);
#endif
/*test_c++.cpp*/
#include "test_c++.h"
int substract(int a, int b)
{
int c;
c = a - b;
return c;
}
C调用C++
/*main.c*/
#include <stdio.h>
#include "test_c.h"
#include "test_c++.h"
int main(void)
{
int x = 3;
int y = 5;
printf("add = %d \n", add(x, y));
printf("sub = %d \n", substract(x, y));
return 0;
}
gcc test_c.c test_c++.cpp main.c -o test_c
但这个时候会报链接错误: main.c:(.text+0x43): undefined reference to 'substract' 。明明我们在test_c++.cpp里面定义了substract(),但是main.c不识别。 这也说明了 c直接调用c++代码出现错误。
修改方法
/*test_c++.h*/
#ifndef TEST_C_PLUSPLUS
#define TEST_C_PLUSPLUS
#ifdef __cplusplus
extern "C" {
#endif
int substract(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
C++调用C
/*main.cpp*/
#include <stdio.h>
#include "test_c.h"
#include "test_c++.h"
int main(void)
{
int x = 3;
int y = 5;
printf("add = %d \n", add(x, y));
printf("sub = %d \n", substract(x, y));
return 0;
}
gcc test_c.c test_c++.cpp main.cpp -o test_cpp
编译结果和上面的是一样的,修改方法类似,在c.h文件里面
/*test_c.h*/
#ifndef TEST_C
#define TEST_C
#ifdef __cplusplus
extern "C" {
#endif
int add(int a, int b);
#ifdef __cplusplus
}
#endif
#endif