extern “C”原理,用法以及使用场景-2016.01.05
1 问题提出
在编程过程中,经常发现如下用法:
#ifndef _FILE_NAME_H_
#define _FILE_NAME_H_ #ifdef __cplusplus
extern "C" {
#endif ...... #ifdef __cplusplus
}
#endif
#endif
这样的代码到底是什么意思呢?首先,__cplusplus是cpp中自定义的宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{和}处理其中的代码。
要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等。而在C中,只是简单的函数名字而已,不会加入其他的信息,也就是说:C++和C对产生的函数名字的处理是不一样的,extern "C"的目的就是主要实现C与C++的相互调用问题。
2 c++中调用c函数
使用场景:
1、 由于系统内核一般是使用C语言来编写的,系统内核中用C语言实现了很多库。而上层应用程序有可能是用C++来开发,如果在内核库函数头文件中不用 extern “C”来声明库函数的话,在编写C++应用程序时,包含库头文件,在C++文件链接时就会以C++标准来链接库的函数名,而在库文件实现时是用C来实现的,二者函数名不同,在链接时就会出现找不到函数的现象。
2、在个人开发工程中,个人熟悉使用c++语言,当.cpp文件要调用.c文件中的函数时,需要extern "C"声明.c文件中的函数,在cpp文件中让c++编译器使用c标准链接c文件中函数。
具体实现:
C函数头文件实现:
//c.h
#ifndef _c_h_
#define _c_h_ #ifdef __cplusplus
extern "C" {
#endif void c_fun(); #ifdef __cplusplus
}
#endif #endif
C函数源文件实现:
#include "c.h" void c_fun()
{ }
C++调用C函数实现:example.cpp中调用c_func函数,
//example.cpp实现 #include "c.h"
int main()
{
c_fun();
return 0;
}
3 c中调用c++函数
当extern “C”放在函数声明之前,并不会改变函数的编译方式,只是指定编译器按照C的标准链接,而不是按照C++的标准去链接函数。因此,如果c++的库要给c调用,显然,不但要在c++头文件中用该宏和extern "c"括起,在cpp中也要这么做。原因就是让cpp编译器将那些代码,编译成c风格。(在Visual Stduio 2010环境中,在c++函数源文件中不使用extern "c",编译出来的函数名字也是按照c风格,而不是c++风格,与前面的在cpp中也需要添加extern "c"不一致,留待后面论证。)
c++函数头文件实现:
#ifndef _cpp_h_
#define _cpp_h_
#ifdef __cplusplus
extern "C" {
#endif void cpp_fun(); #ifdef __cplusplus
}
#endif #endif
c++函数源文件实现:
#include "cpp.h"
extern "C" { //告诉C++编译器,扩号里按照C的命名规则编译
void cpp_fun()
{
}
}
在c中调用c++函数,example.c调用cpp_fun函数:
//example.c实现 #include "cpp.h" int main()
{
cpp_fun();
return 0;
}
上述方案只适合调用C++中的非成员函数,如果你想要在 C 里调用成员函数(包括虚函数),则需要提供一个简单的包装(wrapper)。具体方案参考如下博文:
4 参考资料
http://blog.csdn.net/hxg130435477/article/details/6632954
http://blog.csdn.net/miyunhong/article/details/4589541
extern “C”原理,用法以及使用场景-2016.01.05的更多相关文章
- 2016.01.05 DOM笔记(一) 查找元素
DOM节点的种类 元素和标签是一个意思,例如<body>标签或者称为<body>元素 节点DOM的节点分为三类 元素节点,文本节点,属性节点 例如 <div id=‘b ...
- extern “C”调用测试与验证-2016.01.06
1 调用情形说明 在上一篇关于extern “c”原理以及用法中,详细的说明了为什么需要extern “c”以及如何使用它解决c与c++混合编程时遇到的问题.接下来,使用示例验证方式验证c与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的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”
extern的原理很简单,就是告诉编译器:“你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!”
- 阿里P8架构师谈:数据库分库分表、读写分离的原理实现,使用场景
本文转载自:阿里P8架构师谈:数据库分库分表.读写分离的原理实现,使用场景 为什么要分库分表和读写分离? 类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对 ...
- [官方软件] Easy Sysprep v4.3.29.602 【系统封装部署利器】(2016.01.22)--skyfree大神
[官方软件] Easy Sysprep v4.3.29.602 [系统封装部署利器](2016.01.22) Skyfree 发表于 2016-1-22 13:55:55 https://www.it ...
- http://tedhacker.top/2016/08/05/Spring%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/
http://tedhacker.top/2016/08/05/Spring%E7%BA%BF%E7%A8%8B%E6%B1%A0%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%9 ...
- Murano Weekly Meeting 2016.07.05
Meeting time: 2016.July.05 1:00~2:00 Chairperson: Kirill Zaitsev, from Mirantis Meeting summary: 1. ...
随机推荐
- iphone Dev 开发实例8: Parsing an RSS Feed Using NSXMLParser
From : http://useyourloaf.com/blog/2010/10/16/parsing-an-rss-feed-using-nsxmlparser.html Structure o ...
- 关于c语言中qsort函数的一点心得
今天写c时无意间用到了排序,便想着使用c语言标准库中提供的排序函数,即qsort函数(c++stl中提供了sort函数用于排序),首先是介绍qsort函数的一些基本用法(以下内容转自: http:// ...
- OC知识点
1.@autoreleasepool why1 2.retain O-C内存管理和点语法1>OC内存管理正常情况要使用大量的retain和relrese操作2>点语法可以减少使用retai ...
- python实现字体闪图
!/usr/bin/env python from future import print_function import os.path import sys from optparse impor ...
- python(6)时间戳和北京时间互转,输出当前的时间和推到七天前的日期
项目发展的需要:(包含时间函数)time datetime 时间戳和北京时间互转 import time import datetime s = '2015-04-17 11:25:30' d = d ...
- 实现从sql server存取二进制图片
转:http://www.cnblogs.com/jeffwongishandsome/archive/2009/08/27/1554440.html 1.存取图片(1).将图片文件转换为二进制并直接 ...
- stdlib
system(pause): int cmp(const void *a ,const void *b) { return *(int *)a - *(int *)b ; //从小到 ...
- codeblocks调试快捷键说明
使用codeblocks避免不了快捷键: 在调试程序的时候: 首先在view->toolbar->debugger调出来:快捷方式可以自己看 RUN to Cursor :F4 单步调试 ...
- SQL递归查询
WITH cte AS ( AS lvl FROM Department UNION all FROM cte c inner join Department d ON c.Pid = d.Id ) ...
- TFS如何设置在客户端独占签出
步骤:1.打开源代码管理资源管理器,点击“工作区”的下拉框,选择,“工作区”2.选择编辑3.选择“高级”4.进入编辑工作区,tfs中“位置”选项中,默认的时本地,如果想独占签出,这里我们就必须设置成“ ...