C++和C相互调用
实际工程中C++和C代码相互调用是不可避免的
C++编译器能够兼容C语言的编译方式
C++编译器会优先使用C++编译的方式
extern关键字能强制让C++编译器进行C方式的编译

extern "C"
{
  // do C-style compilation here
}

假设在C++中调用用C语言编写的库,如何来做?
举个简单的小例子:

add.h

int add(int a, int b);

-----------------------------------

add.c
#include "add.h"
int add(int a,int b)
{
  return a + b;
}

gcc -c add.c -o add.o
将会生成一个add.o的文件

-------------------------------------

main.cpp
#include <stdio.h>
#include "add.h"

int main()
{
  int c = add(1,3);
  printf("c = %d\n",c);
}
编译:g++ main.cpp add.o
编译出错:undefined reference to 'add(int ,int )'
利用nm命令查看add.o中是否有add函数
nm add.o,查看发现里面已经有了add函数。那么这个地方为什么提示没有呢

因为add.o是用C语言编译器进行编译的,而main.cpp是C++代码,它想调用C的代码,而C的代码已经被编译成目标文件了。
此处需要强制让C++编译器使用C语言的编译器。
main.cpp
#include <stdio.h>
extern "C"
{
#include "add.h"
}

int main()
{
  int c = add(1,3);
  printf("c = %d\n",c);
}

-----------------------------------------------------------------------------------------

如何保证一段C代码只会以C的方式被编译?
利用extern "C"不就可以了吗?
注意:extern "C"是C++中才有的,C语言中不支持extern "C"这样的写法。
现在要保证的是一段C代码只会以C的方式被编译,不管是C++编译器还是C语言编译器。

你可能还是会说,我就用extern "C"。当采用C语言编译器编译带有extern "C"的语句时,是编译不过的。
解决方案:
__cplusplus是C++编译器内置的标准宏定义
__cplusplus的意义
确保C代码以统一的C方式被编译成目标文件
#ifdef __cplusplus
extern "C" {
#endif

//C-Style Complitation

#ifdef __cplusplus
}
#endif
--------------------------------------

main.c
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif #include "add.h" #ifdef __cplusplus
}
#endif int main()
{
int c = add(,);
printf("c=%d\n",c);
return ;
}

这样用C语言编译器就通过了
同样利用C++编译器也能编译过。

注意事项:
C++编译器不能以C的方式编译重载函数
编译方式决定函数名被编译后的目标名
-C++编译方式将函数名和参数列表编译成目标名 (可以编译完成后,用nm命令查看)
-C编译方式只将函数名作为目标名进行编译

小结:
函数重载是C++对C的一个重要升级
函数重载通过函数参数列表区分不同的同名函数
extern关键字能够实现C和C++的相互调用。(extern代码块中,不能有重载函数)
编译方式决定符号表中的函数名的最终目标名。

本质上是不允许函数名相同的,只不过C++编译器在编译的时候,将参数作为了函数名的一部分。这就是为什么函数名相同还能编译过的地方。而C语言就不行(它在编译的时候,函数名就是函数名,没有参数列表,因此就无法区分同名函数了,因此就没有重载的概念了),这就是因为编译方式的不同,导致的结果

C++和C的相互调用的更多相关文章

  1. Android和JavaScript相互调用的方法

    转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...

  2. 多个Activity相互调用和Intent

    MainActivity.java和OtherActivity.java的相互调用 首先MainActivity.java是Android程序自带的,新建一个类OtherActiviy extends ...

  3. JS代码和OC代码的相互调用

    JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我 ...

  4. C程序与Lua脚本相互调用

    Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...

  5. Unity3D中C#和js方法相互调用

    通过查找资料,Unity3D中C#和js要相互调用彼此的方法,js文件必须放在"Standard Assets". "Pro Standard Assets" ...

  6. Unity3d 脚本相互调用

    unity中三种调用其他脚本函数的方法 第一种,被调用脚本函数为static类型,调用时直接用  脚本名.函数名().很不实用…… 第二种,GameObject.Find("脚本所在物体名& ...

  7. Lua与C++相互调用

    {--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} ...

  8. 关于action script与js相互调用的Security Error问题

    大家都知道,as和js相互调用可以通过ExternalInterface.call和ExternalInterface.addCallback来进行. 比较好的做法是使用之前通过ExternalInt ...

  9. Java与.NET 的Web Services相互调用

    一:简介 本文介绍了Java与.NET开发的Web Services相互调用的技术.本文包括两个部分,第一部分介绍了如何用.NET做客户端调用Java写的Web Services,第二部分介绍了如何用 ...

  10. Android消息机制之实现两个不同线程之间相互传递数据相互调用

    目的:实现两个不同线程之间相互传递数据相互调用方法. 线程一中定义mainHandler 并定义一个方法mainDecode 线程二中定义twoHandler 并定义一个方法twoEncode 实现当 ...

随机推荐

  1. 扎西平措 201571030332 《面向对象程序设计(java)课程学习进度条》

    <2019面向对象程序设计(java)课程学习进度条> 周次 (阅读/编写)代码行数 发布博客量/评论他人博客数量 课余学习时间(小时) 学习收获最大的程序 阅读或编译让我 第一周 20/ ...

  2. 非阻塞式I/O

    套接字的默认状态是阻塞的.这就意味着当发出一个不能立即完成的套接字调用时,其进程将被投入睡眠,等待相应的操作完成.可能阻塞的套接字调用可分为以下4类 (1)输入操作,包括read,readv,recv ...

  3. day48_9_9 前端之javascript与jQuary

    一.BOM与DOM BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行“对话. DOM (Document Object Model) ...

  4. lua 11 闭包,函数的使用

    转自:http://book.luaer.cn/_41.htm 当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称作词法定界.虽然这看起来很清楚,事实并非如此 ...

  5. Spring Boot 自定义Intercepter

    在 SpringBoot2.X 中 ,WebMvcConfigurerAdapter 被deprecated , 更好的做法是 implements WebMvcConfigurer 一.自定义拦截器 ...

  6. 洛谷 P5595 【XR-4】歌唱比赛

    洛谷 P5595 [XR-4]歌唱比赛 题目传送门 题目描述 小 X 参加了一场歌唱比赛. 经过一路鏖战,小 X 终于挺进了决赛,他的对手是小 Y. 这场歌唱比赛的冠军是由点赞数决定的,谁的点赞数高, ...

  7. <String> 179 ,6, 168

    179. Largest Number 冒泡排序,每一轮都把最小的数字选出放在最后. class Solution { public String largestNumber(int[] nums) ...

  8. 用scanf清空缓冲区 对比fflush

    fflush会将缓冲数据打印到屏幕或者输出磁盘,scanf将丢弃. 如上图.

  9. Pycharm2019.2.4专业版激活

    Pycharm2019.2.4专业版激活 IDE是开发者创建程序时使用的的软件包,它通过简单的用户界面集成多个高度关联的组件,从而最大化提升编程体验和生产效率:本质上,IDE是一种改进代码创建.测试和 ...

  10. python运维开发常用模块(6)发送电子邮件模块smtplib

    1.模块常用方法 SMTP类定义:smtplib.SMTP([host[,port[,local_hostname[, timeout]]]]),作为SMTP的构造函数,功能是与smtp服务器建立连接 ...