extern是C/C++语言中表明函数和全局变量 作用范围(可见性)的关键字.
它告诉编译器,其 声明的函数和变量可以在本模块或其它模块中使用。
1。对于extern变量来说,仅仅是一个变量的声明,其并不是在定义分配内存空间。如果该变量定义多次,会有连接错误
2。通常, 在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。也就是说c文件里面定义,如果该函数或者变量与开放给外面,则在h文件中用extern加以声明。所以外部文件只用include该h文件就可以了。而且编译阶段,外面是找不到该函数的,但是不报错。link阶段会从定义模块生成的目标代码中找到此函数。
3。与 extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。

后面转载,阅读中。。。。。。。
  被 extern "C"修饰的变量和函数是按照C语言方式编译和连接的;
未加extern “C”声明时的编译方式

  首先看看C++中对类似C的函数是怎样编译的。

  作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:

void foo( int x, int y );

  该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。

  _foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。

  同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所 编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

   未加extern "C"声明时的连接方式

  假设在C++中,模块A的头文件如下:

// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif

  在模块B中引用该函数:

// 模块B实现文件 moduleB.cpp
#include "moduleA.h"
foo(2,3);

  实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!

   加extern "C"声明后的编译和连接方式

  加 extern "C"声明后,模块A的头文件变为:

// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif

  在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:

  (1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

  (2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

  如果在模块A中函数声明了foo为 extern "C"类型,而模块B中包含的是 extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。

  所以,可以用一句话概括 extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):

  实现C++与C及其它语言的混合编程。

  明白了C++中 extern "C"的设立动机,我们下面来具体分析 extern "C"通常的 使用技巧。

  4. extern "C"的惯用法

  (1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

extern "C"
{
#include "cExample.h"
}

  而在C语言的头文件中,对其外部函数只能指定为 extern类型,C语言中不支持 extern "C"声明,在.c文件中包含了 extern "C"时会出现编译语法错误。

  笔者编写的C++引用C函数例子工程中包含的三个文件的源代码如下:

/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif
/* c语言实现文件:cExample.c */
#include "cExample.h"
int add( int x, int y )
{
 return x + y;
}
// c++实现文件,调用add:cppFile.cpp
extern "C"
{
 #include "cExample.h"
}
int main(int argc, char* argv[])
{
 add(2,3);
 return 0;
}

  如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加 extern "C" { }。

  (2)在C中引用C++语言中的函数和变量时,C++的头文件需添加 extern "C",但是在C语言中不能直接引用声明了 extern "C"的该头文件,应该仅将C文件中将C++中定义的 extern "C"函数声明为 extern类型。

  笔者编写的C引用C++函数例子工程中包含的三个文件的源代码如下:

//C++头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif
//C++实现文件 cppExample.cpp
#include "cppExample.h"
int add( int x, int y )
{
 return x + y;
}
/* C实现文件 cFile.c
/* 这样会编译出错:#include "cExample.h" */
extern int add( int x, int y );
int main( int argc, char* argv[] )
{
 add( 2, 3 );
 return 0;
}

  如果深入理解了第3节中所阐述的 extern "C"在编译和连接阶段发挥的作用,就能真正理解本节所阐述的从C++引用C函数和C引用C++函数的惯用法。对第4节给出的示例代码,需要特别留意各个细节。

关于extern用法说明相关推荐

  1. extern用法详解(转)

    extern用法详解(转)       1 基本解释 extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义. 另外,extern ...

  2. extern用法详解

    [转]extern用法详解 Posted on 2011-08-16 11:15 单鱼游弋 阅读(98) 评论(0)编辑收藏 1 基本解释 extern可以置于变量或者函数前,以标示变量或者函数的定义 ...

  3. 《C关键字分析》之extern用法

    <C关键字分析>之extern用法 一.假设为三方提供库源码和头文件 1.共享库部分 sanf.c #include <stdio.h> int a; void hello() ...

  4. extern 用法详解

    在C语言中,修饰符extern用在变量或者函数的声明前,用来说明"此变量/函数是在别处定义的,要在此处引用".(extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文 ...

  5. 一文彻底搞懂extern用法

    一.定义和声明的区别 声明:用来告诉编译器变量的名称和类型,而不分配内存,不赋初值. 定义:为了给变量分配内存,可以为变量赋初值. 注:定义要为变量分配内存空间:而声明不需要为变量分配内存空间. 二. ...

  6. C++ extern用法总结

    1.extern用法总结 在C语言中,修饰符extern用在变量或者函数的声明前,用来说明"此变量/函数是在别处定义的,要在此处引用". (1)extern修饰变量的声明 如果文件 ...

  7. c语言中extern变量,C语言中的Extern用法

    C语言中的Extern用法 (2010-07-28 12:50:39) 标签: 杂谈 分类: 技术 C语言中的Extern用法 网上有很多帖子问C语言中Extern的用法,而且回答的详细程度各尽不同. ...

  8. C/C++中 extern用法

    一.定义和声明的区别 声明用来告诉编译器变量的名称和类型,而不分配内存,不赋初值. 定义为了给变量分配内存,可以为变量赋初值. 注:定义要为变量分配内存空间:而声明不需要为变量分配内存空间. 二.ex ...

  9. C# 关键字extern用法

    C# 关键字extern用法 修饰符用于声明在外部实现的方法.extern 修饰符的常见用法是在使用 Interop 服务调入非 托管代码时与 DllImport 属性一起使用:在这种情况下,该方法还 ...

  10. const和extern用法

    1.什么是const?    常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const? const 推出的初 ...

最新文章

  1. iPhone手机获取uuid 安装测试app
  2. C语言程序设计 练习题参考答案 第七章 (2) 指针与数组 main函数形参
  3. 【模板】一维树状数组
  4. Windows Phone 7 使用Canvas Grid StackPanel进行布局管理
  5. java Hibernate
  6. python io密集 多线程_python多进程和多线程究竟谁更快(详解)
  7. 解决无法连接mysql问题
  8. 295.数据流的中位数
  9. 用计算机玩吃鸡,W10电脑系统玩吃鸡游戏会卡顿怎么办
  10. 安装 Ubuntu 21.04 后必备的绝佳应用大合集(持续更新中)
  11. 百度搜索算法全解析SEO课程笔记
  12. CES 2017 DAY1:自动驾驶延续昨日热潮,其他产品更强调实用
  13. UR机器人返回信息格式解析
  14. 2020起重机械指挥模拟考试题库及起重机械指挥实操考试视频
  15. Redis 启动的三种方法
  16. matlab灰度图像分割标记,matlab – 分割灰度图像
  17. 国服Cytus2解密与注入
  18. 学Python该看什么书?12本精华好书推荐!
  19. 数据结构(二)栈和队列练习题
  20. 【云速建站】一键生成手机页

热门文章

  1. Single Scale Retinex 增强 matlab 实现
  2. devc++ value of xxx too large for field of 4 bytes at xxx 并且源文件未编译
  3. NLP领域的最新研究进展
  4. python pyttsx3实现文字朗读
  5. 在线查看.doc,.docx,.ofd,.PDF,.WPS以及Office文档的在线解析方式。
  6. 树莓派4b入门之开发RFID系统—两种MFRC522读写脚本
  7. GreenDao笔记
  8. 最好用的Ins客户端:Flume pro for mac
  9. Jmeter 中断言操作
  10. 【C语言】数据类型的扩充和截断