2007年7月12日星期四 19:00 - 2007年7月14日星期六 0:30 (ver:0.01)
在对extern这个关键字没有讲解之前,我们先来了解一下C++的编译器和链接器的基本工作原理。C++的编译器是对文件为单位进行语法的编译,并生成依文件为名字.obj文件,而链接器是把全部.obj文件整合为一个文件的范围进行链接,生成目标文件的。
现在我们对编译器和链接器有了个大概的概念。可以对extern 这个C++关键字的作用进行分析了。extern 关键字的作用有两种。
1. 声明外部变量
告诉编译器某个字符没有在本文件中声明的,而是在整个工程的其他文件中声明的且是全局的,本文件只是引用这个全局符号而已。用法如下:
//main.cpp extern int i; void main() { i=0; }
|
//file.cpp int i;
|
如果我们把main.cpp中的 extern 去掉在编译的时候是可以通过的,因为它是已文件为单位,但是到了链接器的时候就会出错,在链接完成后,它的可见范围被扩大到了整个程序。所以它发现有重复定义的存在。
由上述说链接器把所有的.obj文件化为一个整体,那语法作用域范围就变成为一个文件范围了。既然最终是一个文件作用域范围,那只要在一个地方定义其他地方是可以调用的了。
按照这个思路我们修改程序如下看会出现怎样的结果。
//main.cpp //extern int i; void main() { i=0; }
|
//file.cpp int i;
|
结果是编译器报告出错。说 i=0; 变量I没有定义。我们在把//extern int i; 这行的注释去掉就可以编译成功了。所以说extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”
2. 在C++文件中调用的此函数要以C的方式来编译此函数
C++编译器和C编译器他们对同一个变量和函数编译出来的代码是不一样的。因为C++中对C函数进行了功能上的扩展,如函数重载等。有时我们用C++代码调用现有的C代码时,编译器通过了,但是链接器会报错。就是因为C++编译出来的obj中的变量和函数的符号和C编译器编译出来的符号不一样导致链接器在链接所有的obj文件时找个到相匹配的字符,所就报错了。这时我们就得告诉编译器用C方式来编译C++文集中要调用C文件中的那个变量或函数,用C++中的 extern “C” 变量或函数 这时C++编译器发现文件中有这样的关键字存在,他就把属于extern “C” 这个范围的变量或函数用C方式来编译。
这样链接器就可以找到相关的匹配字符了。如果有多个需要C方式编译的函数和变量的存在,我们可以这样写 extern “C”
{
int a;
void fun();
}
代码如下:
//main.cpp extern “C” { int a; void fun(); } void main() { fun(); }
|
//f.c void fun() {} |
在VC.NET 环境中我们可以用下面的设置来自定义以C编译还是C++编译。