C和C++各自有自身的重要功能,为了能够做到充分利用,避免重复造轮子,有的时候,我们会用到混合编程。然而,我们知道,代码从编写到能执行之前,仍需要经过编译、链接阶段。通常,编译每一个单元文件会生成目标文件,然后链接器会把各个目标文件链接起来生成可执行性文件。链接器之所以能把目标文件相互之间链接起来,就是通过查找目标文件中的唯一函数符号(即经过编译器去编译修饰后,重新得到的函数符号)。但是C和C++编译器对编译函数符号的生成规则是不一样的,为什么呢?因为C只有单一的命名空间,不支持函数重载之类的特性,例如对于函数void fun(int a, int b),经过编译后生成的符号为_fun, C链接器链接的时候就会去找_fun这样的函数符号;C++为了支持函数重载(即函数名字可以相同,参数类型或个数不同),允许存在同名的函数,这一点在C中是做不到的。其实,C++甚至可以存在相同的类型、变量等,因为在C++中命名空间的存在。在C++中,对于函数void fun(int a, int b),经过编译后,生成的类似为_fun_int_int, 新生成的符号名不仅带有函数名,还有参数类型。正因为他们两者编译函数的时候,生成的符号规则不一样,所以,在混合编程中,如果我们不进行任何处理,而相互效用的话,必然会出现在链接的时候,找不到符号链接的情况。

为实现混合编程,我们不得不提到extern "C" , extern "C"是C++的特性,是一种链接约定,通过它可以实现兼容C与C++之间的相互调用,即对调用函数能够达成一致的意见,使用统一的命名规则,使得实现方提供的接口和调用方需要的接口经按照指定规则编译后,得到的都是一致的函数符号命名。具体用法,请看如下实例。

一、C++调用C函数实例(关键是让C++调用的C接口按照C规范走即可)

// --------------cfun.h
#ifndef __C_FUN_20180228_H__
#define __C_FUN_20180228_H__#ifdef __cplusplus
extern "C"{
#endif // __cplusplusvoid cfun();
#ifdef __cplusplus
}
#endif#endif

cfun.h头文件中,使用了条件编译#ifdef __cplusplus, 表示如果是C++来调用该接口,则该函数接口经编译后的函数符号生成规则按照C风格走, 否则没有extern "C" , 这样提供的接口同时支持C和C++两者的调用。

// --------------cfun.c
#include "cfun.h"
#include <stdio.h>void cfun()
{printf("hello world.\n");
}
// --------------main.cpp
#include <iostream>
#include "cfun.h"int main()
{cfun();system("pause");return 0;
}

二、C调用C++函数实例(关键是让C调用的C++函数接口按照C规范走即可)

// --------------cppfun.h
#ifndef _CPP_FUN_20180228_H__
#define _CPP_FUN_20180228_H__extern "C" void cppfun();#endif
// --------------cppfun.cpp#include "cppfun.h"
#include <iostream>void cppfun()
{std::cout << "hello world." << std::endl;
}
// --------------main.c#include <stdio.h>
extern void cppfun();
int main()
{cppfun();system("pause");return 0;
}

C与C++之间的相互调用(混合编程)相关推荐

  1. VS2013和MATLAB相互调用混合编程

    Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): MA ...

  2. 【环境】VS2013和MATLAB相互调用混合编程

    Visual Studio和MATLAB混合编程,有两种方法: 1 MATLAB调用C程序: 2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能): 前一 ...

  3. iOS架构-多工程联编及framework之间的相互调用(19)

    对于大公司,大工程来说,业务线很多,也时刻在变,功能模块要求能随时下线,或者业务不再需要了,就需要从主工程中移除相关工程或者库.以减小包的大小.多工程联编是一种多业务合作的一种方法. 有篇文章写的很详 ...

  4. Python与C之间的相互调用

    Python与C之间的相互调用(Python C API及Python ctypes库) 分类: [Python]2010-01-24 17:58 32468人阅读 评论(11) 收藏 举报 pyth ...

  5. C#与Javascript变量、函数之间的相互调用2008年11月28日 星期五 05:28 P.M.1.如何在JavaScript访问C#函数?

    C#与Javascript变量.函数之间的相互调用 2008年11月28日 星期五 05:28 P.M. 1.如何在JavaScript访问C#函数? 2.如何在JavaScript访问C#变量? 3 ...

  6. js 中meta 移除head_JS函数和winform函数之间的相互调用

    1.写一个简单的html页面,用于输入日志,代码如下: <html><head> <meta charset="UTF-8"> <scri ...

  7. 关于cocos2d-x 和安卓之间的相互调用

    最近在研究cocos2d游戏移植安卓需要调用很多方法,所以在研究之中写下它们之间相互调用 首先,cocos2d调用安卓 在一个.h文件中添加头文件 #include <jni.h> #in ...

  8. 父窗口、子窗口和Silverlight之间的相互调用

    啊哈~ 爷爷,爸爸,儿子~ 三代同堂~ 前两天做 silverlight 的东西,主页面打开一个子页面,然后子页面中包含一个 silverlight 应用程序 那难免会涉及到他们三者相互调用的问题 其 ...

  9. python 函数定义先后是否会影响函数之间的相互调用?(不影响)

    # -*- coding: utf-8 -*- """ @File : 201006_测试是否能将被调用函数写在被调用函数之后.py @Time : 2020/1/6 1 ...

最新文章

  1. c++string 输入换行符
  2. mysql取消mvvc机制_MySQL探秘(六):InnoDB一致性非锁定读
  3. 物联网linux_Linux的未来,Google的物联网标准等
  4. fiddler网站请求被拦截怎么恢复?
  5. javascript内置属性
  6. Qt实现名字的幸运大抽奖
  7. Office2010安装相关问题及解决方法
  8. MATLAB学习笔记02-MATLAB的数据类型
  9. 如何让我的世界变成别人的世界(国际版)——HMCL启动器之如何同时用到mod和光影
  10. #35 insert
  11. 华硕美版路由器RT-AC1200G+解决无线信号弱问题
  12. html 图片右侧空白,CSS缩小窗口时,背景图出现右侧空白
  13. 钟茜的工作日志跟在这里
  14. SkyEye天目全数字实时仿真软件功能介绍
  15. java properties map_为什么java.util.Properties实现Map而不是Map
  16. 低档计算机配置 新闻,一台电脑配置的高低,主要看这四方面
  17. SAP License:术语歪解
  18. 使用友盟快速分享与第三方登录注意事项
  19. CSS3——多媒体查询属性
  20. IDEA创建JavaFX项目并打包成jar包和exe可执行文件

热门文章

  1. 三端集成稳压器的外形和种类
  2. python-docx 设置 word 文档中表格格式
  3. 时钟服务器linux,简单搭建NTP时钟服务器
  4. Java都到16了,为什么都还在用8,是越做越烂了么?
  5. 十行代码,用Python做一个迷你版的美图秀秀
  6. 删除列表中的空格(其他元素)的4种方法
  7. 字符编码与文件的基本操作
  8. 在统计学中_统计学中的几个基本概念
  9. 搜狗拼音输入法 for Mac OS
  10. chrome91.0.4472.77(正式版本)(64位) windows和mac跨域解决