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. 【第4题】 什么是https

    https是基于http和SSL/TLS实现的一个协议,他可以保证在网络上传输的数据都是加密的,从而保证数据安全. 接下来我们从http协议开始,提出想法并逐步进行分析,最终实现Https. 1. h ...

  2. 全网最新方法:win10下如何安装和配置64位JDK-13

    1.下载JDK-13 下载链接:https://www.oracle.com/technetwork/java/javase/downloads/index.html 2.安装JDK-13 双击下图的 ...

  3. 【转】基于Bootstrap的超酷jQuery开关按钮插件

    基于Bootstrap的超酷jQuery开关按钮插件

  4. [C9] 降维(Dimensionality Reduction)

    降维(Dimensionality Reduction) 动机一:数据压缩(Motivation I : Data Compression) 数据压缩允许我们压缩数据,从而使用较少的计算机内存或磁盘空 ...

  5. 第04组 Alpha冲刺(6/6)

    队名:new game 组长博客:戳 作业博客:戳 组员情况 鲍子涵(队长) 燃尽图 过去两天完成了哪些任务 协调了一下组内的工作 复习了一下SuffixAutomata 接下来的计划 实现更多的功能 ...

  6. FineUIPro v6.0.0 大版本更新,快来围观!

    本月末(2019-09-20),我们会发布激动人心的 FineUI v6.0.0 版本,这个版本将带来一系列的重要更新! 在列举新版本特性之前,我们先来回顾下每次发布大版本的关键时间点: v1.0.0 ...

  7. webpack-实用的2个配置

    ①:运行npm run dev 后自动打开浏览器    首先找到config里面的index.js文件,然后打开找到autoOpenBrowser属性,把默认的false改为true即可 ②:简写路径 ...

  8. 使用wireshark学习TCP

    TCP标志位: 在TCP传输中,标志位用于表示特定的连接状态或提供额外信息.每个标志位占用1比特.常用的TCP标志位包含以下几种: SYN Synchronous,TCP三次握手建立连接的第一步,主动 ...

  9. 在进行机器学习建模时,为什么需要验证集(validation set)?

    在进行机器学习建模时,为什么需要评估集(validation set)? 笔者最近有一篇文章被拒了,其中有一位审稿人提到论文中的一个问题:”应该在验证集上面调整参数,而不是在测试集“.笔者有些不明白为 ...

  10. SAP PI接口(RFC类型)在函数字段修改或增加后,出现字段映射错误问题

    在解决标题所言问题之前,我们先回头看看RFC和sproxy这两种接口的优缺点. 关于PI接口的实现,目前我了解到的各大国企项目像中海油.中石化.国网等,普遍实现方式是RFC和代理类sproxy这两种. ...