extern “C”的用法
引言
由于不同的代码互相调用起来很容易出错,甚至同一种代码但由不同的编译器编译,为实现C++代码调用其他C语言代码,会在C语言代码的部分加上extern "C",表明这段代码需要按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约。
extern "C"中的"C"指的不是一种语言,而是一种编译和链接的规约,表示符合C语言的编译和连接规约的任何语言,如Fortran、assembler等。所以并不能改变其语义,在编写被加上extern "C"的代码时还是要遵守C++的类型检测和参数转换规则。
该文章从以下方面解释extern "C"用法:
- 1、extern "C"双重含义
- 1.1、 extern
- 1.2、"C"
- 2、C与C++的相互调用
- 2.1、 C++ 调 C
- 2.2、C调 C++
1、extern "C"双重含义
extern "C" 包含双重含义,从字面上可见得它有两个部分,"extern"和"C"。
1.1、 extern
全局函数、变量等在所有的源文件是一致的,只能被定义一次,但可以被声明多次:
//sample1.c
int a = ;
//sample2.c
extern int a;
在以上代码sample2.c中使用的 a 是定义在sample1.c里的。变量 a 在所有文件中只能被定义一次否则出错,但可以被声明多次,每次声明要保持类型一致。sample2.c中的 extern 表示 a 变量在此仅仅是一个声明,而不是定义。
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数。
与extern对应的关键字是 static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。
1.2、 "C"
被extern "C"修饰的变量和函数是按照类C语言方式编译和链接的。
C++作为一种面向对象的语言,C++支持函数重载,需要在函数名字中加入函数参数,而过程式语言C则不支持,所以函数名不会被更改。例如,当函数原型为:
void func ( int a , float b );
该函数被 C 编译器编译后在符号库中的名字为 _func,而C++编译器则将函数名中加入函数参数,变为 _func_int_float 。
同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。
2、C与C++的相互调用
2.1、 C++ 调 C
C++中调用的C语言包含在C语言头文件时,可如此调用:
extern "C" {#include "sample_c.h"}
完整例子如下:
//c语言头文件:sample_c.h
#ifndef SAMPLE_C_H
#define SAMPLE_C_H
extern int plus( int a, int b);
#endif //c语言实现文件:sample_c.c
#include "sample_c.h"
int plus( int a, int b){
return a+b;
} //c++文件:sample_cpp.cpp
extern "C"{
#include "sample_c.h"
}
int main( int argc, int **argv){
plus( , );
}
2.2、 C 调 C++
C语言中不支持extern "C"声明,所以调用起C++来和C++调用C有点区别。
//C++头文件:sample_cpp.h
#ifndef SAMPLE_CPP_H
#define SAMPLE_CPP_H
extern "C" int plus( int a, int b);
#endif //C++实现文件:sample_cpp.cpp
#include "sample_cpp.h"
int plus( int a, int b){
return a+b;
} //C实现文件:sample_c.c
extern int plus( int a ,int b);//C语言中在此写#include "sample_cpp.h"会出错
int main(){
plus( , );
}
extern “C”的用法的更多相关文章
- 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语言完全相同. ...
- extern "C"的用法解析(转)
原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html 1.引言 C++语言的创建初衷是“a better C ...
- 【转载】extern "C"的用法解析(原博主就是抄百度百科的,不如另外一篇好)
[说明]文章转载自Rollen Holt 的文章 http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html --------- ...
- [转载] extern "C"的用法解析
本文转载自: http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html 1.引言 C++语言的创建初衷是“a better ...
- extern "C"的用法
文章转自开源电子论坛:http://www.openedv.com/forum.php?mod=viewthread&tid=7986 看一些程序的时候老是有 “#ifdef __cplusp ...
- 转:extern "C"的用法解析
1.引言 C++语言的创建初衷是“a better C”,但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言, C++保留了一部分过程式 ...
- [C语言学习笔记二] extern 函数的用法
extern 用来定义一个或多个变量.其后跟数据类型名和初始值.例如: extern int a =10 它与 int,long long int,double,char的本质区别,在于 extern ...
- 关于extern "C" 的用法
而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误 ...
随机推荐
- JavaScript——基本语法
单词掌握 BOM 浏览器对象模型 DOM 文档对象模型 document 文档 break 中断 continue 继续 1.js脚本位置 通常可以在三个地方编写js脚本代码,一是在网页文件的< ...
- JavaScript中纯JS写21点游戏
// 21点游戏 分为人机对战和人人对战 // 玩家每次抽一张牌 牌的点数为1-10点随机数 谁更接近21点谁就获胜 let readline = require("readline-syn ...
- URL类发送请求
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import jav ...
- threading线程中的方法(27-11)
t1.start() # 执行线程 t1.join() # 阻塞 t1.setDaemon(True) #守护线程 threading.current_thread() # 查看执行的是哪一个线程 t ...
- mysql数据库字段bigint使用
Mysql里有个数据类型bigint 在java转换成实体对象时,处理不当容易出现以下异常: java.lang.ClassCastException: java.lang.Long cannot b ...
- innerHTML 属性用于获取或替换 HTML 元素的内容。
innerHTML 属性 innerHTML 属性用于获取或替换 HTML 元素的内容. 语法: Object.innerHTML 注意: 1.Object是获取的元素对象,如通过document.g ...
- T3118 01完美矩阵【计数,前缀和,差分,好题】
Online Judge:未知 Label:好题,计数,前缀和 题目描述 一个01矩形被称为是完美01矩形,如果满足下面3个条件: (1)它的四条边上都是1 (2)内部(除了4条边)的0和1的个数之差 ...
- linux 解压 WinRAR 压缩文件
1.Download rar for linux wget http://www.rarlab.com/rar/rarlinux-x64-5.5.b1.tar.gz 2.Configure rar t ...
- BZOJ1912:[APIO2010]patrol巡逻
Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...
- 逻辑回归代码demo
程序所用文件:https://files.cnblogs.com/files/henuliulei/%E5%9B%9E%E5%BD%92%E5%88%86%E7%B1%BB%E6%95%B0%E6%8 ...