extern "C"解析
转自大牛的解析(非常具体详细)http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html
我做个简单的标注方便以后自己查看:
在用C++的项目源码中,经常会不可避免的会看到下面的代码:
#ifdef __cplusplus //采用c++,自动定义__cplusplus的宏
extern "C" {
#endif /*...*/ #ifdef __cplusplus
}
#endif
extern "C" 是为了实现C++与C及其它语言的混合编程,由于C++支持函数重载,同名函数在编译阶段会根据参数特征表的不同命名不同的全局名称,如:
C++中 void func(int,int) 命名为 _func_int_int
而C方式编译后命名为 _func
3.2、C的编译和连接
C语言中并没有重载和类这些特性,故并不像C++那样print(int i),会被编译为_print_int,而是直接编译为_print等。因此如果直接在C++中调用C的函数会失败,因为连接是调用C中的print(3)时,它会去找_print_int(3)。因此extern "C"的作用就体现出来了。
3.3、C++中调用C的代码
假设一个C的头文件cHeader.h中包含一个函数print(int i),函数前面的extern可加可不加,函数默认即为外部链接的(其他文件中声明引用也不需要要extern关键字,原作者这里有误)。它的代码如下:
#ifndef C_HEADER
#define C_HEADER extern void print(int i); #endif C_HEADER
相对应的实现文件为cHeader.c的代码为:
#include <stdio.h>
#include "cHeader.h"
void print(int i)
{
printf("cHeader %d\n",i);
}
现在C++的代码文件C++.cpp中引用C中的print(int i)函数:
extern "C"{ //即告诉编译器这里面是按C语言编译和链接的,调用这里的函数也按C的方式来进行
#include "cHeader.h"
}
int main(int argc,char** argv)
{
print();
return ;
}
执行程序输出:
![]()
3.4、C中调用C++的代码
现在换成在C中调用C++的代码,这与在C++中调用C的代码有所不同。如下在cppHeader.h头文件中定义了下面的代码:
#ifndef CPP_HEADER
#define CPP_HEADER extern "C" void print(int i); #endif CPP_HEADER
相应的实现文件cppHeader.cpp文件中代码如下:
#include "cppHeader.h" #include <iostream>
using namespace std;
void print(int i)
{
cout<<"cppHeader "<<i<<endl;
}
在C的代码文件c.c中调用print函数:
extern void print(int i);
int main(int argc,char** argv)
{
print();
return ;
}
注意在C的代码文件中直接#include "cppHeader.h"头文件,编译出错。而且如果不加extern int print(int i)编译也会出错。
extern "C"指令非常有用,因为C和C++的近亲关系。注意:extern "C"指令中的C,表示的一种编译和连接规约,而不是一种语言。C表示符合C语言的编译和连接规约的任何语言,如Fortran、assembler等。
还有要说明的是,extern "C"指令仅指定编译和连接规约,但不影响语义。例如在函数声明中,指定了extern "C",仍然要遵守C++的类型检测、参数转换规则。
再看下面的一个例子,为了声明一个变量而不是定义一个变量,你必须在声明时指定extern关键字,但是当你又加上了"C",它不会改变语义,但是会改变它的编译和连接方式。
如果你有很多语言要加上extern "C",你可以将它们放到extern "C"{ }中。
PS: extern 用于变量和函数
之于变量
player.h:
//全局命名空间
int a=20;//全局变量默认是extern的
static int b=10;//定义内部链接的变量
xxx.cpp:
extern int a;// 只声明,不能重复定义
之于函数
函数默认都是外部链接的(如库文件定义的函数也都没有加extern关键字)
player.h:
void foo(){.....}
xxx.cpp:
#include "player.h";
//包含头文件后,直接用就行了
extern "C"解析的更多相关文章
- C/C++中extern关键字解析
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- extern "c"用法解析
转自: extern "c"用法解析 - 简书 引言 C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言, ...
- 探索C++的秘密之详解extern "C",这就是为什么很多.lib被我们正确调用确总是无法解析的。
(转载,绝对的有用) lib被我们正确调用确总是无法解析.这是C++编译和C编译的区别 时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus extern "C&qu ...
- extern "C" 用法解析
extern "c"用法解析 作者 作者Jason Ding ,链接http://www.jianshu.com/p/5d2eeeb93590 引言 C++保留了一部分过程式语言的 ...
- 解析“extern”
解析“extern” 1. 声明外部变量 现代编译器一般採用按文件编译的方式,因此在编译时,各个文件里定义的全局变量是 互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部.以下举一个简单的 ...
- DLL模块:extern "C"的简单解析
1.揭密extern "C" extern "C"包含双重含义,从字面上即可得到:首先,被它修饰的目标是 "extern”的:其次,被它修饰的目标是 ...
- C/C++之extern "C"的用法解析
extern "C"的用法解析 http://blog.sina.com.cn/u/494a1ebc010004g5 C++中extern “C”含义深层探索 1.引言 C++语言 ...
- ZT extern "C"的用法解析
extern "C"的用法解析 1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同. ...
- (转)探索C++的秘密之详解extern "C",这就是为什么很多.lib被我们正确调用确总是无法解析的。
(转载,绝对的有用) lib被我们正确调用确总是无法解析.这是C++编译和C编译的区别 时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus extern "C&qu ...
随机推荐
- Linux安全层详解
1 bastion(安全堡垒系统)通常配置两个服务: 1 服务定义系统的功能: 2 服务支持远程访问: 原则: 1 不需要某个软件卸载掉: 2 需要某个软件但不使用就不要激活: 为各个bastion系 ...
- linux下编译openjdk8
一.准备工作 1.0 工作环境 Ubuntu 12.04,32位机 1.1.安装JD ...
- oracle 11g 版本自带移除,省时省力
---oracle删除 app\Administrator\product\11.2.0\dbhome_1\deinstall.bat 指定要取消配置的所有单实例监听程序 [LISTENER]: En ...
- python并发编程相关概念总结
1.简述计算机操作系统中的“中断”的作用? 中断是指在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序.待处理完毕后又返回 ...
- nable to execute dex: Multiple dex files define Lcom/chinaCEB/cebActivity/R
用proguaid 只混淆Android项目的src下的包的话,如果出现了上面的问题: nable to execute dex: Multiple dex files define Lcom/chi ...
- Redis实现之数据库(三)
过期键删除策略 在Redis实现之数据库(二)一小节中,我们知道了数据库键的过期时间都保存在过期字典中,又知道了如果根据过期时间去判断一个键是否过期,现在剩下的问题是:如果一个键过期了,那么它什么时候 ...
- vue2.x生命周期
vue2.x生命周期 1. beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用. 2. created 实例已经创建 ...
- 设计模式之第9章-原型模式(Java实现)
设计模式之第9章-原型模式(Java实现) “快到春节了,终于快放假了,天天上班好累的说.”“确实啊,最近加班比较严重,项目快到交付了啊.”“话说一到过节,就收到铺天盖地的短信轰炸,你说发短信就发吧, ...
- Java GUI编程4---标签组件JLabel
Java GUI编程4---标签组件JLabel 2018年06月11日 22:06:58 蓝蓝223 阅读数 12103更多 个人分类: Java书籍摘抄 所属专栏: Java Swing图形界面 ...
- python基础-集合小结
Python-基础-集合小结 集合 简介 声明 常用操作 成员关系 新增删除 集合间操作 其他 补充 集合 简介 python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和 ...