C/C++ extern “C“ 的问题
声明
文章中的部分代码引用来在:
https://blog.csdn.net/u012234115/article/details/43272441
场景
今天在CSDN中看到了一篇关于 extern “C” 相关的文章, 这让我想起了之前解决相关问题的场景。
具体如下:
PC端图形工具是基于QT开发的,控制端使用MCU开发。因为有某些代码需要和PC端共享,所以该段代码是用C写的。当PC端合入该代码后发现总是编译报错。后来发现是C代码那边并没有考虑C++的场景。也许很多MCU开发者都不会考虑这个问题。而实际上好的代码一般都不会存在这个问题。
为什么
是不是经常在大型C项目的 .h 中看到如下的代码:
#ifdef __cplusplus
extern "C"
{
#endif
//一段代码
#ifdef __cplusplus
}
#endif
我们知道C++是可以兼容C代码的,.h 文件其实是C的头文件,这种写法的目的是当C文件用于C++项目时告诉编译器这是C文件。
具体如下:
__cplusplus这个关键字是C++中特有的, 当定义了该宏就表示这是C++环境。(具体这个定义的含义因编译和C++标准不同而有所不同但是这里不重要)。如代码所示如果是C++环境即加入extern “C” 。
要明白为何使用extern "C",还得从C++中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等。而在C中,只是简单的函数名字而已,不会加入其他的信息,也就是说 C++和C对产生的函数名字的处理是不一样的。
如下一段简单的代码,对比加入和不加入extern "C"产生的汇编代码:
int f(void)
{
return 1;
}
加入extern "C"时候产生的汇编代码:
.file "test.cxx"
.text
.align 2
.globl _f
.def _f; .scl 2; .type 32; .endef
_f:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
不加入extern "C"产生的汇编代码:
.file "test.cxx"
.text
.align 2
.globl __Z1fv
.def __Z1fv; .scl 2; .type 32; .endef
__Z1fv:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret
两段汇编代码同样都是使用gcc -S命令产生的,所有的地方都是一样的,唯独是产生的函数名,一个是_f,一个是__Z1fv。
总结
工作中发现一些朋友并不清楚甚至不知道extern ”C"的作用。这或许与个人的开发领域单一有关,用心观察会发现一些MCU的库头文件其实都有这些标注。
努力吧!
C/C++ extern “C“ 的问题的更多相关文章
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- 16-static和extern关键字2-对变量的作用
上一讲介绍了static和extern对函数的作用,static用来定义一个内部函数,不允许其他文件访问:extern用来定义和声明一个外部函数,允许其他文件访问.static和extern对变量也有 ...
- 15-static和extern关键字1-对函数的作用
一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.ob ...
- 转:C++项目中的extern "C" {}
引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __c ...
- extern "c"用法解析
转自: extern "c"用法解析 - 简书 引言 C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言, ...
- extern
gcc编译器编译程序有四个阶段,预处理.编译.汇编.链接.预处理阶段会将源代码中的包含的头文件如stdio.h编译进来:编译阶段,gcc首先要检查代码的规范性.是否有语法错误等,以确定代码的实际要做的 ...
- 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)
李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...
- extern用法总结
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明"此变量/函数是在别处定义的,要在此处引用".1. extern修饰变量的声明. 如果文件a.c需要引用b.c中变量 ...
- 链接(extern、static关键词\头文件\静态库\共享库)
原文链接:http://www.orlion.ga/781/ 一. 多目标文件的链接 假设有两个文件:stack.c: /* stack.c */ char stack[512]; int top = ...
随机推荐
- FAQ:Linux 查看服务器型号(R730为例)
命令:dmidecode -t system | grep -e Manufacturer -e Product 查询结果: Manufacturer: Dell Inc. Product Name: ...
- ArrayList底层原理、线程安全及其相关集合(面试常问)
一.ArrayList底层原理 1.特点及其原理:ArrayList底层基于数组实现,查找快,增删慢 2.ArrayList底层原理,初始化及调用add()方法添加元素: 默认初始化容量为10 第一次 ...
- nlp入门(三)基于贝叶斯算法的拼写错误检测器
源码请到:自然语言处理练习: 学习自然语言处理时候写的一些代码 (gitee.com) 数据来源:norvig.com/big.txt 贝叶斯原理可看这里:机器学习算法学习笔记 - 过客匆匆,沉沉浮浮 ...
- 半导体行业通信标准SECS/GEM协议一看就懂的
半导体行业通信标准SECS/GEM透析 HSMS通信的设备端通常为客户端(Equipment)(也可称为Active 在通信中主动连接对方的),工厂会部署服务端(Host)(也可称为Passive 被 ...
- 论文解读(TAMEPT)《A Two-Stage Framework with Self-Supervised Distillation For Cross-Domain Text Classification》
论文信息 论文标题:A Two-Stage Framework with Self-Supervised Distillation For Cross-Domain Text Classificati ...
- AgileConfig-1.7.0 发布,支持 SSO 🎉🎉🎉
AgileConfig 已经好久好久没有更新过比较大的功能了.一是 AgileConfig 本身的定位就是比较轻量,不想集成太多的功能.二是比较忙(懒).但是本次升级给大家带来了一个比较有用的功能 S ...
- Azure Storage 系列(八)存储类型细化分类说明
一,引言 Azure 存储账户功能经过官方改进迭代后,在创建的时候,存储账户的类型被分为两大类: 1)general-purpose v2 account(标准常规用途v2) Blob 存储,队列存储 ...
- 简单了解PyCharm
简单了解PyCharm PyCharm的简单使用 修改主题 1 2 切换解释器 1 如何创建pythin文件 1 2 3 4 注释语法 行注释 这里是注释 块注释 '''这里是注释''' 常量和变量的 ...
- 使用pycharm脚本发送钉钉群通知
使用Pychon脚本发送钉钉群通知 我们可以使用钉钉的机器人助手发送群通知,只需要非常简单的配置就可以实现,而没有任何的成本. 1) 首先我们要在钉钉群里添加一个机器人助手 选择智能群助手,然后选择添 ...
- 白盒AES和SM4实现的差分故障分析
DFA攻击背景介绍 传统的密码安全性分析环境被称为黑盒攻击环境,攻击者只能访问密码系统的输入与输出,但随着密码系统部署环境的多样化,该分析模型已经不能够反映实际应用中攻击者的能力.2002年,Chow ...