C++中extern关键字使用(转)
参考文章:http://blog.csdn.net/sruru/article/details/7951019
chapter1、如何混合编译C语言和C++
实际开发过程中,C++中会调用C与语言编写的代码,我在网络上面找到一篇写得很好的文章
http://blog.csdn.net/keensword/article/details/401114
方法一、全局函数和变量在devVar.c文件中实现,在extern.cpp文件中使用extern关键字声明在devVar.c文件中定义的函数和变量。
devVar.c文件的代码如下所示:
- #include <stdio.h>
- int i = 1;
- void func()
- {
- printf("%d",i++);
- }
extern.cpp文件中代码如下所示:
- #include "stdafx.h"
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- //#include "devVar.h"
- //extern int i;
- //extern void func();
- extern "C"
- {
- extern int i;
- extern void func();
- //#include "devVar.h"
- }
- int main(void)
- {
- for (int x = 0;x < 10; x++)
- {
- func();
- }
- }
所以在C++文件中编译C文件需要使用extern "C"关键字,声明语法如下所示
extern "C"
{
采用C语言实现的内容
}
方法二、
在devVar.h文件中实现C代码(即devVar.h作为C语言头文件),在.cpp文件中包含C语言头文件。
devVar.h头文件内容为:
- #include <stdio.h>
- int i = 1;
- void func()
- {
- printf("%d",i++);
- }
extern.cpp文件内容如下所示
- #include "stdafx.h"
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- //#include "devVar.h"
- //extern int i;
- //extern void func();
- extern "C"
- {
- //extern int i;
- //extern void func();
- #include "devVar.h"
- }
- int main(void)
- {
- for (int x = 0;x < 10; x++)
- {
- func();
- }
- }
其中,包含C语言头文件的方式为:
- extern "C"
- {
- //extern int i;
- //extern void func();
- #include "devVar.h"
- }
写到这里,楼主又产生了一个疑问,上面的例子讲的是C++调用C实现的代码,那如果是C调用C++编写的代码呢?
楼主作了如下改动:
devVar.cpp代码为:
- #include <stdio.h>
- int i = 1;
- void func()
- {
- printf("%d",i++);
- }
extern.c文件代码为
- #include <stdio.h>
- extern int i;
- extern void func();
- int main(void)
- {
- int x = 0;
- for (;x < 10; x++)
- {
- func();
- }
- }
单独编译每个文件都通过,链接声称可执行文件的时候报错:
1>extern.obj : error LNK2019: unresolved external symbol _func referenced in function _main,说明.c文件中extern void func(),按照C编译的规则,得到函数_func,而devVar.cpp文件采用C++编译方式,得到的函数为XX·!_func(具体楼主也不知道哈),这样链接的时候函数自然找不到,那怎么解决呢?
需要在devVar.cpp中,明确调用extern "C"关键字,声明cpp文件中有关代码,需要按照C的方式来生成,修改devVar.cpp文件如下所示:
- #include <stdio.h>
- int i = 1;
- extern "C" void func()
- {
- printf("%d",i++);
- }
此时,除了需要使用extern "C"声明编译的时候采用C方式编译外,.cpp文件中的代码可以按照C++方式编写,例如
devVar.cpp按照下面方式写,也是正确的。
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- int i = 1;
- extern "C" void func()
- {
- cout << "i = " << i++ << endl;
chapter 2 . extern关键字的作用
extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数,也会在当前文件的后面或者其它文件中定义,来看下面的例子。
- // extern.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- extern int i;
- extern void func();
- int _tmain(int argc, _TCHAR* argv[])//typedef wchar_t _TCHAR;#define _tmain wmain
- {
- i = 0;
- func();
- return 0;
- }
- int i;
- void func()
- {
- i++;
- cout << "i = " << i << endl;
- }
上面代码中变量i和函数func在文件末尾定义,所以变量需要使用extern关键字告诉编译器,变量在别的地方定义。extern int i我原来以为extern i就可以,结果编译器报错,仔细想下确实应该,否则编译器不知道i是什么类型的数据,又怎么能判断i = 0是否是一个正确的赋值语句呢?
那么定义在其他文件中的函数和变量,如何通过extern关键字调用呢?
首先,定义在其它文件中的函数和变量,可以使用两种方法调用:
一、使用头文件调用,这时候,函数和变量必须在头文件中定义和声明。
二、使用extern关键字调用,这时候函数和变量在.cpp或者.c文件中定义和声明。
看下面两个例子:
devVar.cpp函数中定义:
- #include "stdafx.h"
- int i;
extern.cpp中
- // extern.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- extern int i;
- extern void func();
- int _tmain(int argc, _TCHAR* argv[])//typedef wchar_t _TCHAR;#define _tmain wmain
- {
- i = 0;
- func();
- return 0;
- }
- void func()
- {
- i++;
- cout << "i = " << i << endl;
- }
编译工程,程序输出:i = 1,这里使用extern关键字声明在其它cpp文件中定义的变量和函数。
#include <filensme> --- 将filename文件中的内容插入到新的文件中。
deVar.h文件中代码为
- #include <stdio.h>
- int i = 1;
- void func()
- {
- printf("%d",i++);
- }
函数func修改全局变量i的值并输出。
extern.cpp文件内容为:
- #include "stdafx.h"
- #include <stdio.h>
- #include <iostream>
- using namespace std;
- #include "devVar.h"
- //extern int i;
- //extern void func();
- int main(void)
- {
- for (int x = 0;x < 10; x++)
- {
- func();
- }
- }
程序输出1,2,3,4,5,6,7,8,9,10,这里#include <filname.h> 包含定义在其它头文件中的函数和变量,在来看一个例子。
- // extern.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- extern int i;
- extern int func(int);//这里extern必需的,函数定义在其它cpp文件中
- int _tmain(int argc, _TCHAR* argv[])//typedef wchar_t _TCHAR;#define _tmain wmain
- {
- i = 100;
- func(i);
- return 0;
- }
devVar.cpp文件中内容为:
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- int i;
- int func(int a)
- {
- i = a;
- cout << "i = " << i << endl;
- return 0;
- }
这样,同样是输出了i= 100。
能够使用extern引用其它cpp文件中定义的函数说明了一个问题:
如果一个工程现编译cpp文件,在把多个目标文件链接成为可执行文件,而两个或多个文件中,定义了相同的全局变量,那么,程序编译的时候不会报错,因为编译器单独编译每个文件,在链接可执行文件的时候,由于多个目标文件中含有相同的全局变量,而生成可执行文件的时候,任何文件中定义的全局变量对其它目标文件都是可见的,此时由于变量定义冲突而发生错误。看下面的代码:
- // extern.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- int i;
- extern int func(int);//这里extern是必须的函数定义在别的cpp文件中
- int _tmain(int argc, _TCHAR* argv[])//typedef wchar_t _TCHAR;#define _tmain wmain
- {
- i = 100;
- func(i);
- return 0;
- }
devVar.cpp文件中,内容为:
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- int i;
- int func(int a)
- {
- i = a;
- cout << "i = " << i << endl;
- return 0;
- }
单独compile任何一个cpp文件都是对的,但是 编译工程,生成可执行文件的时候报错:
1>LINK : D:\vctest\extern\Debug\extern.exe not found or not built by the last incremental link; performing full link
1>devVar.obj : error LNK2005: "int i" (?i@@3HA) already defined in extern.obj
1>D:\vctest\extern\Debug\extern.exe : fatal error LNK1169: one or more multiply defined symbols found
原因是:两个.cpp文件中都定义了全局变量i,变量重复定义了。
PS:定义在.h文件中的函数和变量不能使用extern变量声明,原因是#include <filename>在预编译的时候将.h文件中的内容插入了cpp文件中,因此编译器找得到在其它.h文件中定义的变量或者函数。编译的时候,只编译cpp文件的内容,.h文件时不参与编译,如果使用extern声明在.h文件中定义的变量或者函数,那么声明为extern的变量和函数在其它.cpp文件中找不到,因此程序编译的时候就发生了错误。
C++中extern关键字使用(转)的更多相关文章
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C++中extern关键字用法小结
总结C++中关于extern关键字的用法. 1.变量的生明和定义中 C++语言支持分离式编译机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译.为了将程序分为许多文件,则需要在文件中共享代码 ...
- C/C++中extern关键字解析
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- C/C++中extern关键字详解
转自:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变 ...
- C/C++中extern关键字详解(转)
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- [UE4]C++中extern关键字浅谈
变量声明和变量是有区别的 extern int i; //只是声明i而非定义i int j; //声明而且还定义了j 任何一个显式初始化的声明都将成为定义,而不管有没有extern,extern语句一 ...
- iOS 中 const static extern 关键字总结
在看一些高手所写的代码时,总是可以看到我们小白平常不用的关键字,一次,两次,三次,不能总是不明不白,现在总结一下日常开发中常用的关键字的作用: 关键字const/static/extern的释义和用法 ...
- C语言中的 extern 关键字
今天在 BLE 中看到很多 extern 关键字,现在总结一下: extern 关键字主要用于在一个c文件中要用到另一个c文件中的变量或者函数. example: #extern_base.c ; # ...
- 【转载】理解C语言中的关键字extern
原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...
随机推荐
- IE 弹出"Unable to do xml/xsl" Processing
解决方法:
- php5.4下安装ECshop出现错误的解决办法
转:http://www.programmernote.com/?p=65 1.安装是会提示 Warning: date_default_timezone_get(): It is not safe ...
- (转载)浅谈javascript的分号
(转载)http://www.blueidea.com/tech/web/2009/7261.asp javascript的分号代表语句的结束符,但由于javascript具有分号自动插入规则,所以它 ...
- 游戏开发设计模式之对象池模式(unity3d 示例实现)
前篇:游戏开发设计模式之命令模式(unity3d 示例实现) 博主才学尚浅,难免会有错误,尤其是设计模式这种极富禅意且需要大量经验的东西,如果哪里书写错误或有遗漏,还请各位前辈指正. 原理:从一个固定 ...
- App被拒绝的原因收录
转自:dApps开发者 » APP被苹果App Store拒绝的79个原因(未完待续) 1.程序有重大bug,程序不能启动,或者中途退出.2.绕过苹果的付费渠道,我们之前游戏里的用兑换码兑换金币.3. ...
- java IO复习(三)
package com.zyw.io; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; ...
- cocoaPods教程
<#这个不是命令,包括尖括号#> 一.源设置 1. 查看源,终端输入: sudo gem sources -l 2. 删除已有的源,如: sudo gem sources --remo ...
- Oracle索引(B*tree与Bitmap)的学习总结
在Oracle中,索引基本分为以下几种:B*Tree索引,反向索引,降序索引,位图索引,函数索引,interMedia全文索引等,其中最常用的是B*Tree索引和Bitmap索引.(1).与索引相关视 ...
- 53个要点提高php效率
用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说 ...
- C# WinForm 透明控件 PictureBox透明 分类: WinForm 2014-07-30 13:27 591人阅读 评论(0) 收藏
1.要实现C# WinForm中的控件与背景的透明,可以通过设置控件的BackColor属性为Transparent,同时设置其父控件.因为在C#中,控件的透明指对父窗体透明.如果不设置Parent属 ...