C++中extern "C"的设立动机是实现C++与C及其它语言的混合编程。 C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:
void foo(int x, int y);
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。 C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
C++中 extern "C" 的两种用法:
1. 如果要在C++程序中调用C语言写的函数, 在C++程序里边用 extern "C" 修饰要被调用的这个C程序,告诉C++编译器此函数是C语言写的,是C语言编译器生成的,调用他的时候请按照C语言习惯传递参数等。如:
//在C++程序里边声明该函数
extern "C" int strcmp(const char *s1, const char *s2);
注意:用带给定名字的C链接声明多于一个函数是错误的,例如:
extern "C" void print(const char *);
extern "C" void print(int);
在C++程序中,重载C函数是很常见的,但是,重载集合中的其他函数必须都是C++函数。例如:
class SmallInt{};
class BigNum{};
extern "C" double calc(double);
extern "C" SmallInt calc(const SmallInt& );
extern "C" BigNum calc(const BigNum& );
可以从C程序和C++程序调用calc的C版本。其余的函数是带类型参数的C++函数,只能从C++程序调用。声明的次序不重要。
2. 用C++语言写的一个函数,如果想让这个函数可以被其他C语言程序所用,则用extern "C" 来告诉C++编译器,请用C语言习惯来编译此函数。如:
extern "C" int strcmp(const char *s1, const char *s2)
{
while (*s1 && *s1++ == *s2++) {
}
return *s1 - *s2;
}