- 论坛徽章:
- 0
|
向大家求教extern "C"{...}的问题。
C++编译器使用一种称为"Name Mangling"的机制来支持函数重载和类型安全的链接。例如下面的重载函数:
void f(int);
void f(char);
经常被C++编译器处理为类似_f_int()和_f_char()这样的“内部”名字,用以区分重载函数,以及在链接的过程中保证对函数的调用被解析到正确的代码上。
设想你在C++程序中调用C的库函数。由于C没有重载的概念,类型系统也比C++弱,所以C编译器是不做Name Mangling的。如下面的函数声明:
void f(int, char);
被C++编译器处理后的名字应该是类似_f_int_char()这样的,但是假设这个函数是一个C库函数,你只有它的声明(头文件)和实现(已经编译过,供链接的库文件),而库文件中的符号表是C编译器生成的,这个函数的“内部”名字是_f()。链接的时候linker无法将对_f_int_char()的调用解析到_f()上,自然会出现链接错误。
解决的办法就是用下面的声明:
extern "C" void f(int, char);
告诉C++编译器,这不是一个C++函数,编译时需要按照C语言的规则来处理名字,以便linker能够正确链接。
可以用下面的格式集中声明很多这种函数:
extern "C" {
fun1();
fun2();
...
}
也可以用下面的格式,将一个头文件中的全部函数,声明为按照其他语言的编译方式来处理。
extern "C" {
#include <stdio.h>;
}
注意extern "C"修饰的函数按照C的编译调用方式来处理,因此下面的代码是违法的:
extern "C" {
int f(int);
int f(double);
}
即声明为extern "C"的函数不允许重载。 |
|