1.extern是c/c++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在“全局”范围中使用
2.exterc “C”("C"必须大写)包含两重含义:首先,被它修饰的目标是“extern”的;其次,被它修士的目标是“C”的。
3.由于extern表达的是“全局”的含义,而static关键字则表明变量或函数只能局限在单个模块内使用,所以一个函数或变量只能被模块使用时,不能用extern “C”修饰。
4.作为一种面向对象的语言,C++支持函数重载,而c语言则不支持。正是由于这个原因,全局变量或函数被c++编译后在符号库中的名字与c语言的不同。
void fun(int x, int y);在c++中编译后可能是_fun_int_int(不同编译器中不同),而在c语言中由于不存在函数重载,编译器对全局变量或函数的名字进行的处理时非常简单的,只要在c源程序中的名字前加上一个下划线“_”(即_fun),就可以生成编译时说需要的符号。
5.采用c和c++混合编程,或者c++中使用c函数库时,都需要使用extern “C”,以完成对特定全局变量或函数的链接任务。
(1)C++程序调用C函数
/**************invoke.cpp**********/
using namespace std;
int value();
int main(){
cout<<value()<<endl;
}
/********end ofinvoke.cpp**********/
/****value.c*****/
int value(){
return 5;
}
/*****end of value.c*****/
在value.c中value()在目标文件中的名字是_value,而invoke.cpp中,函数声明中的value()被c++编译器解析成
?value@@YANHZ,因而连接发生错误。因此在invoke.cpp中,要用extern "C"告诉编译器:按照c语言规范解析函数名value,即这样声明:
extern "C"{
int value();
}
由于c函数一般以库函数的形式提供的,而函数声明都放在头文件中,所以c++源程序中国应将包含头文件的语句至于extern "C"块中,即
extern "C"{
#include "header.h"
}
(一种典型的情况是,如果c++程序调用c语言编写的.DLL,当包含.DLL的头文件或声明接口函数时,应该使用extern “C”)
(2)c程序调用c++函数
一般的做法是让c++源文件在编译时,采用c语言的对全局变量和函数的编译规范。也就是说,c++源程序中使用extern “C”对函数名或全局变量名进行修饰。
/*********invoke.h***********/
extern "C"{
void show();
}
/**********end of invoke.h***********/
/*********invoke.cpp***********/
#include<cstdio>
#include "invoke.h"
void show(){
printf("Hello!");
}
/*********end of invoke.cpp***********/
/*********main.c***********/
void show();
int main(){
show();
}
/*********end of main.c***********/
在c++源文件invoke.cpp中,为了让函数void show();能够被c语言程序调用,必须用extern “C”通知编译器采用c语言的规则解析函数名。这个工作可以在头文件invoke.h中完成。但是c语言源文件main.c中,却不能直接包含invoke.h,因为c语言不支持extern “C”声明,在.c文件中包含了extern “C”时会出现编译错误。所以,在main.c中,应该直接进行函数原型的声明,即声明void show();,这样编译器可在所有参与连接的目标文件中寻找名字为_show的函数完成函数调用。