extern "C" 是C++中的一个关键字组合,用于告诉C++编译器按照C语言的链接约定(linkage)来处理变量或函数。
使用extern "C"可以防止C++的名称修饰(name mangling),从而使得C++代码可以和C代码相互调用。
C++ 调用 C 代码
场景:你现在开发的项目是C++做的,现在需要引入一个三方库,三方库是用C语言开发和编译的。
简单模拟下这种情况,假设以下三个文件(sum.h、sum.c、main.cpp)在同一目录下:
// file sum.h
#ifndef __SUM_H__
#define __SUM_H__
int addSum(int a, int b);
#endif // __SUM_H__
// file sum.c
#include "sum.h"
int addSum(int a, int b)
{
return a + b;
}
gcc -o sum.o -c sum.c // 按C语言编译
// main.cpp
#include <stdio.h>
extern "C"
{
#include "sum.h" // 按c处理sum.h文件
}
int main(int argc, char *argv[])
{
int res = addSum(3, 4);
printf("%d\n", res);
return 0;
}
g++ -o main.o -c main.cpp // 按C++语言编译
gcc main.o sum.o // 链接
C 调用 C++ 代码
场景:你用 C++ 开发了一个库提供给其他开发人员使用,你想兼容下 C 语言,即其他用 C 语言项目可以调用你的 C++ 库。
同样简单模拟下这种情况,假设以下三个文件(sum.h、sum.cpp、main.c)在同一目录下:
// file sum.h
#ifndef __SUM_H__
#define __SUM_H__
// 实际编译后是按C处理的
#ifdef __cplusplus
extern "C"
{
#endif
int addSum(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
// file sum.cpp
#include "sum.h"
int addSum(int a, int b)
{
return a + b;
}
g++ -o sum.o -c sum.cpp // 按C++语言编译,但通过 extern "C" 来修饰函数,让编译器按C语言来处理。
#include <stdio.h>
#include "sum.h"
int main(int argc, char *argv[])
{
int res = addSum(3, 4);
printf("%d\n", res);
return 0;
}
gcc -o sum.o -c main.c // 按C语言编译
gcc main.o sum.o // 按C语言链接
总结
如果 C 是被调用方,调用方是 C++,那么调用方用 extern "C" 去修饰 C 函数声明。
如果 C++ 是被调用方,调用方是 C,那么被调用方用 extern "C" 去修饰 C++ 函数声明,被调用方要主动去兼容 C。
这样 C 和 C++ 就可以互相调用了。