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. 【简单的spfa+优先队列】

    题目是给出只有x和y构成的图,相同元素走路不花费,不同元素间花费1,给出起点终点,最少花费是 #include<cstdio>#include<algorithm>#inclu ...

  2. C++ 模板类示例 template class

    声明和实现在一个文件中: template<class T> class book { public: book(); ~book(); private: }; template<c ...

  3. 【Eureka篇三】Eureka集群配置(5)

    1. 新建子模块microservicecloud-eureka-7002(后面简称7002) 和 microservicecloud-eureka-7003(后面简称为7003),packaging ...

  4. nodejs 连接MySQL后,输出数据带有RowDataPacket、中括号大括号怎么去掉?

    var mysql = require('mysql'); var connection = mysql.createConnection({ host : 'localhost', user : ' ...

  5. vue-cli2.0和vue-cli3.0中当发布到生产环境时禁用console.log

    vue-cli2.0中的方法 1.安装插件 npm install uglifyjs-webpack-plugin --save-dev 2.修改webpack.prod.conf.js配置文件 co ...

  6. 禁用software reporter tool.exe 解决CPU高占用率的问题

    或者 或者 C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\SwReporter\36.184.200 下编辑 manifes ...

  7. java架构之路-(JVM优化与原理)JVM的运行时内存模型

    还是我们上次的图,我们上次大概讲解了类加载子系统的执行过程,验证,准备,解析,初始化四个过程.还有我们的双亲委派机制. 我们这次来说一下运行时内存模型.上一段小代码. public class Mai ...

  8. 简单ALV得演示(用到了ALV可编辑及保存后修改数据库)

    *&---------------------------------------------------------------------* *& Report YPMRP010_ ...

  9. ASP.NET Core launchsettings.json 文件

    ASP.NET Core launchsettings.json 文件 在本节中,我们将讨论在 ASP.NET Core 项目中launchsettings.json文件的重要性. launchset ...

  10. Python - 标准库概况 - 第二十一天

    Python 标准库概览 操作系统接口 os模块提供了不少与操作系统相关联的函数. 建议使用 "import os" 风格而非 "from os import *&quo ...