如何有效解决C与C++的相互调用问题

from:https://blog.csdn.net/gobitan/article/details/1532769

在实际工作中可能经常要进行C和C++的混合编程,C++调用C语言的代码通常都比较容易,但也有一些细节需要注意。C要调用C++的代码就略为麻烦一些,因为C不支持面向对象的特征。

一、C++调用C

首先我们来看一下C++调用C语言的代码。要让你的C代码既能被C代码又能被C++调用虽说容易,但是还是有需要注意的地方。现有三个文件分别如下:
/* file TestC.h */
#ifndef TESTC_H
#define TESTC_H
#ifdef __cplusplus
extern "C" 
{
#endif
int add(int a, int b);
#ifdef __cplusplus
}
#endif
#endif /* TESTC_H */
/* file TestC.c */
#include "TestC.h"
int add(int a, int b)
{
return (a + b);
}
/* file TestCpp.cpp */
#include "stdio.h"
#include "TestC.h" //TestC.h是C的头文件
int main()
{
printf("add = %d/n", add(2, 5));
return 0;
}
说明:
file TestC.h是C的头文件,file TestC.c是其实现文件,file TestCpp.cpp是调用C函数的C++文件。
文件TestC.h中的TESTC_H定义是为了头文件保护,” #ifdef __cplusplus”这个不能缺少,你可以去查看C的标准库头文件中都有这个,如”stdio.h”。有了这个宏编译器就知道现在是C还是C++在调用它。
为什么要区分C与C++调用呢?其深层次原因是因为C和C++编译器在编译和链接时对于函数的处理不一样。C++为了支持函数重载在编译时会加入函数参数及类型信息。如上面的add方法,C编译器编译后在符号库中的名字为_add,而C++编译器则会产生像_add_int_int之类的名字。C++正是依靠这种机制实现了函数的重载。
extern关键字表示将函数或变量声明为全局类型,与之相对应的是static。static限定函数或变量的作用域为本文件。extern还有一个作用就是与”C”连在一起使用,即extern “C”通知编译器将extern “C”所包含的代码按照C的方式编译和链接。

二、C调用C++

下面我们就来看看如何在C语言中使用C++的代码(包括C++类的方法)。为了简单起见,我将类的定义和实现放在一个文件中(通常应该是将分别放在.h和.cpp文件中)。自定义类文件(这里省略了头文件保护等其它细节)如下:
//* file TestClass.h */
class HJH
{
public:
int add(int a, int b)
{
return (a + b);
}
};
将C++类封装为C函数的文件(为了简略也将声明和实现放在了同一个文件中)如下:
/* file TestCpp.cpp */
#include "TestClass.h"
extern "C" int add_cpp(int a, int b);
int add_cpp(int a, int b)
{
HJH hjh;
return hjh.add(a, b);      
}
实际调用C++代码的C文件如下:
/*file TestC.c */
#include "stdio.h"
extern int add_cpp(int a, int b);
int main()
{
printf("add_cpp = %d/n", add_cpp(2, 5));
return 0;
}
上面的过程很清晰,就是用一个函数将C++类的使用封装起来,然后将它外部声明为C函数就可以了。
文件TestClass.h定义并实现了一个类,该类只有一个add方法。文件TestCpp.cpp定义并实现了一个函数add_cpp,函数中定义了一个HJH类对象并调用了该对象的add方法。然后将add_cpp函数进行外部声明为C。
TestC.c文件中为了使用add_cpp函数,也需要进行外部声明。这是为了通知编译器说明这个函数是在其他文件中实现(注意在C文件中的extern后面不可加”C”)。当这三个文件一起编译链接时,编译器就可以找到add_cpp的具体实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eclipse开发工具之崩溃和备份

1.通过在命令行中输入“where java”,找到除jdk目录下的所有java相关程序,直接删掉(一般会在C:WINDOWSsystem32下)以后再也不用怕找不到目录了 2.内存不足,打开Eclipse目录下的eclipse.ini,把里面的-Xmx512…

IOS-网络(监听网络状态)

1 //2 // BWNetWorkTool.h3 // IOS_0131_检测网络状态4 //5 // Created by ma c on 16/1/31.6 // Copyright © 2016年 博文科技. All rights reserved.7 //8 9 #import <Foundation/Foundation.h> 10 11 interface BWNetWorkTool : NSObject 12 ///是否是WiFi …

C++中的friend详细解析

C中的友元机制允许类的非公有成员被一个类或者函数访问&#xff0c;友元按类型分为三种&#xff1a;普通非类成员函数作为友元,类的成员函数作为友元&#xff0c;类作为友元。友元包括友元的声明以及友元的定义。 友元的声明默认为了extern&#xff0c;就是说友元类或者友元函数…

【VMCloud云平台】拥抱Docker(六)关于DockerFile(1)

之前我们说过通过Docker pull来下载Images创建容器&#xff0c;这一次我们来聊下如何通过DockerFile创建Images再创建容器&#xff0c;Dockerfile也是Docker中的重点&#xff0c;使用DockerFile能够更加便捷轻量的存储标准化环境&#xff0c;也是环境管理的重要手段&#xff0c…

C++中相对路径与绝对路径以及斜杠与反斜杠的区别 及 处理代码

转载自&#xff1a;http://blog.csdn.net/sszgg2006/article/details/8447176文件路径正斜杠和反斜杠正斜杠&#xff0c;又称左斜杠&#xff0c;符号是"/"&#xff1b;反斜杠&#xff0c;也称右斜杠&#xff0c;符号是"\"。文件路径的表示可以分为绝对路径…

01参考资料

《Visual C#经典游戏编程开发》 目标&#xff1a; 掌握小游戏开发的思路&#xff0c;在实际开发过程中&#xff0c;思考实践面向对象&#xff0c;为cocos2d-x开发打下基础转载于:https://www.cnblogs.com/sharpfeng/p/5181260.html

WPF的二维绘图(一)——DrawingContext

DrawingContext比较类似WinForm中的Graphics 类&#xff0c;是基础的绘图对象&#xff0c;用于绘制各种图形&#xff0c;它主要API有如下几种&#xff1a; 绘图API 绘图API一般形为DrawingXXX系列&#xff0c;常用的基础的绘图API有&#xff1a; DrawEllipseDrawGeometryDrawG…

Windows系统编程之进程间通信

Windows系统编程之进程间通信作者&#xff1a;北极星2003来源&#xff1a;看雪论坛&#xff08;www.pediy.com&#xff09;Windows 的IPC&#xff08;进程间通信&#xff09;机制主要是异步管道和命名管道。&#xff08;至于其他的IPC方式&#xff0c;例如内存映射、邮槽等这里…

前端知识体系收藏

1. 布局框架&#xff1a; Bootstrap: http://getbootstrap.com/ Foundation: http://foundation.zurb.com/ Uikit: http://www.getuikit.com/ Web Components:http://css-tricks.com/modular-future-web-components// 2. 构建工具及包管理器&#xff1a; Grunt: http://gruntjs…

20分钟快速了解Redis

Redis可以说是目前最火爆的NoSQL数据库&#xff01; 过去几年&#xff0c;Memcached很盛行&#xff0c;现在有很多公司已将Memcached替换成了Redis。当然&#xff0c;很多人替换并不清楚为什么&#xff0c;只是感觉不想让主流抛弃&#xff0c;这也充分反映了目前Redis的强势。 …

进程通信例子

from&#xff1a;https://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.beginoutputreadline(vvs.80).aspx?cs-save-lang1&cs-langcsharp#code-snippet-4备注可同步或异步读取 StandardOutput 流。Read、ReadLine 和 ReadToEnd 等方法对进程的输出流执行…

IDEA15 下运行Scala遇到问题以及解决办法

为了让Scala运行起来还是很麻烦&#xff0c;为了大家方便&#xff0c;还是记录下来&#xff1a; 1、首先我下载的是IDEA的社区版本&#xff0c;版本号为15. 2、下载安装scala插件&#xff1a; 2.1 进入设置菜单。 2.2 点击安装JetBrains plugin 2.3 输入scala查询插件&#xff…

通过扫码自定义链接安装iOS app,版本更新总结。

1、打包ipa&#xff0c;plist工具&#xff1a;xcode6证书&#xff1a;企业级开发证书 1.1&#xff09;xcode6开始企业级打包时不在生成plist&#xff0c;需要自己编写&#xff1a;模版见下&#xff1a; <?xml version"1.0" encoding"UTF-8"?><!…

安排与愿想

机器学习的理论学了好久了&#xff0c;对于回归&#xff0c;分类&#xff0c;聚类&#xff0c;数据的预处理的各种算法也有了深刻认识&#xff1b; 但纸上谈兵&#xff0c;没有意义&#xff1b; 从今天开始用起来吧&#xff0c;把各种算法的实践以及思路记录下来&#xff0c;附…

pdf破解版

网页说明http://aikongke.com/3754.html1118-1805-7284-0295-8107-3663您好 亲 看到您拍的宝贝了&#xff01; 链接&#xff1a;http://pan.baidu.com/s/1c0iE44C 密码&#xff1a;bnyc XI版转载于:https://www.cnblogs.com/computerMatainance/p/5192834.html

使用try-with-resources替代try finally释放资源

2019独角兽企业重金招聘Python工程师标准>>> 1、旧社会 Java里&#xff0c;对于文件操作IO流、数据库连接等开销非常昂贵的资源&#xff0c;用完之后必须及时通过close方法将其关闭&#xff0c;否则资源会一直处于打开状态&#xff0c;直至程序停止&#xff0c;增加…

MFC模态对话框和非模态对话框

MFC中对话框有两种形式&#xff0c;一个是模态对话框&#xff08;model dialog box&#xff09;&#xff0c;一个是非模态对话框&#xff08;modeless dialog box&#xff09;。一、模态对话框&#xff08;model dialog box&#xff09;在程序运行的过程中&#xff0c;若出现了…

平板电脑离寿终正寝还有多远?

近期有评论称&#xff0c;因为大尺寸智能手机越来越普及&#xff0c;小尺寸平板正遭受着越来越严重的冲击&#xff0c;在这样的背景下&#xff0c;平板厂商也纷纷转攻超大尺寸平板市场&#xff0c;以此避开大尺寸智能手机的竞争&#xff0c;只是。这样的策略转变是否能扭转平板…

Swift 与 JSON 数据

转载自&#xff1a; http://www.cnblogs.com/theswiftworld/p/4660177.html 我们大家平时在开发 App 的时候&#xff0c;相信接触最多的就是 JSON 数据了。只要你的 App 有读取网络数据的功能&#xff0c;你就免不了要与 JSON 打交道。比如你做一个新闻 App&#xff0c;你要读取…

TeamViewer - 最好用强大的免费跨平台远程桌面控制软件 (支持电脑和手机)

from&#xff1a;很早以前 LYcHEE 就提到过&#xff0c;家中的潮人爷爷奶奶每天摆弄着电脑&#xff0c;看看新闻发发邮件&#xff0c;安享晚年生活。只是意料之中的&#xff0c;电脑上莫名出现各种问题&#xff1f;不翼而飞的图标&#xff1f;照片又忘记怎么导出了&#xff1f;…