【本文链接】

http://www.cnblogs.com/hellogiser/p/extern.html


【extern 变量/函数】

  extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,有2种方式:

  (1)extern告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。

  (2)extern说明变量或者函数声明在其他的源文件里,而不用include头文件的方式来引用该函数时,链接器在各个模块中搜索这个变量或者函数来进行最终链接。

  与extern对应的关键字是 static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。


【extern_include方案】

extern 变量和函数的声明必须在B.h文件中,其定义必须在B.cpp文件中;在A.cpp中引用的时候要include "b.h"

例如MyClass.h

 C++ Code 
1
2
3
4
5
 
#pragma once

// method 1
extern int myA; // declaration
extern int myAdd(int a, int b); // declaration

MyClass.cpp

 C++ Code 
1
2
3
4
5
6
7
8
9
 
#include "StdAfx.h"
#include "MyClass.h"

// method 1    definition
;
int myAdd(int a, int b)
{
    return a + b;
}

如何在main.cpp中使用?

main.cpp

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
#include "stdafx.h"
#include <iostream>
#include "MyClass.h"  // extern int myA;  extern int myAdd(int,int)
using namespace std;

void test_extern_include()
{
    cout << myA << endl;
    cout << myAdd() << endl;
}

void test_main()
{
    test_extern_include();
}

int main()
{
    test_main();
    ;
}


【extern方案】

MyClass.h

extern 变量必须定义在B.h文件中,extern函数通常定义在B.cpp文件中,也可以定义在B.h文件中。在A.cpp中引用的时候要不能够添加include "b.h",但是要添加extern变量和函数声明。

MyClass.h

 C++ Code 
1
2
3
4
5
 
#pragma once

// method 2
; // definition
int mySub(int a, int b); // declaration

MyClass.cpp

 C++ Code 
1
2
3
4
5
6
7
8
 
#include "StdAfx.h"
#include "MyClass.h"

// method 2    definition
int mySub(int a, int b)
{
    return a - b;
}

main.cpp

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
#include "stdafx.h"
#include <iostream>
//#include "MyClass.h"  // extern int myA;  extern int myAdd(int,int)
using namespace std;

extern int myB;
extern int mySub(int a, int b);

void test_extern()
{
    cout << myB << endl;
    cout << mySub() << endl;
}

void test_main()
{
    test_extern();
}

int main()
{
    test_main();
    ;
}


【extern 变量】
  在一个源文件里定义了一个数组:char a[6];
  在另外一个文件里用下列语句进行了声明:extern char *a;
  请问,这样可以吗? 
  答案与分析:
  不可以,程序运行时会告诉你非法访问。原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]。

【extern 函数】

  当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误,这种情况应该如何解决?

   答案与分析:

   目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去extern这一步。以避免这种错误。


【extern “C”】

  在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,应该如何解决这种情况呢?

  答案与分析:

  C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,这是一个用C写成的函数,请用C的方式来链接它们,不要生成用于链接的中间函数名。

  带extern “C”的代码在处理函数名称时,直接使用函数的名称,不采用特别的方法生成一个中间函数名称;

  而没有带extern ”C”的代码在处理函数名称时,使用特别方法生成一个中间函数名称。所以C++函数在使用C函数时,加上extern “C”才能正确的找到指定的函数。

【解决方案】

1.如果函数库没有考虑C++引用的情况,已生成库文件。我们在使用它的头文件时,可以如此使用可解决连接问题,这样时候后编译在引用cgi.h中的函数时,会按照C语言方式引用:

 C++ Code 
1
2
3
 
extern "C" {
#include "cgi.h"
}

2.如果要写一个C函数库,我们应当尽量采用如下书写方式,而避免C++用户出现1中的问题。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
// at the start of cgi.h
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

//============================
    // cgi source code
    //............................
    //============================
    //at the end of cgi.h
#ifdef __cplusplus
}
#endif /* __cplusplus */

extern关键字总结的更多相关文章

  1. 16-static和extern关键字2-对变量的作用

    上一讲介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量也有 ...

  2. 15-static和extern关键字1-对函数的作用

    一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.ob ...

  3. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  4. C++中extern关键字用法小结

    总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...

  5. 解决全局变量共享---C语言的extern关键字用法

    在调试程序时,有一个参数需要在多个函数之间传递,因为是作为调试参数,不想将参数引入到函数中. 很自然的想到使用全局变量来表示这个公共参数,工程代码的结构如下: main.c test.c test.h ...

  6. C语言中的 extern 关键字

    今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...

  7. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

  8. 浅谈C/C++中的static和extern关键字 转

    原文:http://developer.51cto.com/art/201104/256820.htm static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.extern, &quo ...

  9. 关于全局变量和函数,在其他类中调用问题,extern关键字

    1个工程下有几个类文件,和1个全局的文件comm.h, comm.h中存放了这几个类同时需要的变量和同时调用的函数. 当时,我只在comm.h中定义: int  commData1: vector&l ...

  10. C语言的static和extern关键字

    我的博客:www.while0.com 如果A.c要包含B.c里的一个变量或函数,则在A.c中要用extern关键字声明.注意: ①如果是包含的B.c里的函数,则在A.c里声明的时候可以不写exter ...

随机推荐

  1. [转]DBA,SYSDBA,SYSOPER三者的区别

    原文地址:http://www.oracleonlinux.cn/2010/02/dba_sysdba_sysoper/ 什么是DBA?什么是SYSDBA,什么又是SYSOPER?三者究竟有何联系呢? ...

  2. 坑爹的BFC;块格式上下文

    Formatting context(FC) Formatting context 是 W3C CSS2.1 规范中的一个概念.它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位 ...

  3. 【CodeForces 504A】Misha and Forest

    题 题意 有n个点,代号分别为0到n-1,然后这n个点有d个相连点,相连点的XOR sum 为s,求所有的边. 分析 知识:a^b^a=b,a^b^b=a. 把相连点为1的i存进队列,i的唯一相连点就 ...

  4. 学习笔记-动态树Link-Cut-Tree

    --少年你有梦想吗? --少年你听说过安利吗? 安利一个集训队讲解:http://wenku.baidu.com/view/75906f160b4e767f5acfcedb 关于动态树问题,有多种方法 ...

  5. 装了虚拟机,但是没有虚拟网卡vmnet0 vmnet1 vmnet8

    在服务里面启动图中的两个服务,在再你的虚拟网络编辑器里面点恢复默认设置就会出现了,我的是win8.1,默认这两个服务是手动启动的,可能是优化软件优化的结果 我是win10  里面显示以太网3 和 4, ...

  6. POJ3749 破译密码

    Description 据说最早的密码来自于罗马的凯撒大帝.消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A都分别替换成字母F).而你要获得消息 ...

  7. Tomcat Server Configuration Automation Reinforcement

    目录 . 引言 . 黑客针对WEB Server会有那些攻击面 . 针对Tomcat Server可以做的安全加固 . Managing Security Realms with JMX . 实现对T ...

  8. HackerRank Extra long factorials

    传送门 今天在HackerRank上翻到一道高精度题,于是乎就写了个高精度的模板,说是模板其实就只有乘法而已. Extra long factorials Authored by vatsalchan ...

  9. 由chrome剪贴板问题研究到了js模拟鼠标键盘事件

    写在前面 最近公司在搞浏览器兼容的事情,所有浏览器兼容的问题不得不一个人包了.下面来说一下今天遇到的一个问题吧 大家都知道IE下面如果要获得剪贴板里面的信息的话,代码应该如下所示 window.cli ...

  10. MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论

     MySQL ACMAIN_CHM06-26 16:36 等级 84次回复 [求证&散分]MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论 庆祝本月大版得 ...