C++和C的相互调用
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的相互调用的更多相关文章
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- 多个Activity相互调用和Intent
MainActivity.java和OtherActivity.java的相互调用 首先MainActivity.java是Android程序自带的,新建一个类OtherActiviy extends ...
- JS代码和OC代码的相互调用
JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我 ...
- C程序与Lua脚本相互调用
Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...
- Unity3D中C#和js方法相互调用
通过查找资料,Unity3D中C#和js要相互调用彼此的方法,js文件必须放在"Standard Assets". "Pro Standard Assets" ...
- Unity3d 脚本相互调用
unity中三种调用其他脚本函数的方法 第一种,被调用脚本函数为static类型,调用时直接用 脚本名.函数名().很不实用…… 第二种,GameObject.Find("脚本所在物体名& ...
- Lua与C++相互调用
{--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} ...
- 关于action script与js相互调用的Security Error问题
大家都知道,as和js相互调用可以通过ExternalInterface.call和ExternalInterface.addCallback来进行. 比较好的做法是使用之前通过ExternalInt ...
- Java与.NET 的Web Services相互调用
一:简介 本文介绍了Java与.NET开发的Web Services相互调用的技术.本文包括两个部分,第一部分介绍了如何用.NET做客户端调用Java写的Web Services,第二部分介绍了如何用 ...
- Android消息机制之实现两个不同线程之间相互传递数据相互调用
目的:实现两个不同线程之间相互传递数据相互调用方法. 线程一中定义mainHandler 并定义一个方法mainDecode 线程二中定义twoHandler 并定义一个方法twoEncode 实现当 ...
随机推荐
- Linux 中find命令
1.在当前目录下找以txt结尾的文件 find . -name '*.txt' 2.在当前目录下找以所有字母开头的文件 find . -name '[a-z]*' 3.在/etc 目录下找以host开 ...
- Python基础之猜数游戏
例题一:猜数游戏.在程序中预设一个0~9之间的整数,让用户通过键盘输入所猜的数,如果大于预设的数,显示“遗憾,太大了”:小于预设的数,显示“遗憾,太小了”,如此循环,直至猜中该数,显示“预测N次,你猜 ...
- 【简单的spfa+优先队列】
题目是给出只有x和y构成的图,相同元素走路不花费,不同元素间花费1,给出起点终点,最少花费是 #include<cstdio>#include<algorithm>#inclu ...
- oracle表连接的优化
多表连接的三种方式: HASH JOIN,MERGE JOIN,NESTED LOOP NESTED LOOP: 嵌套循环连接,适用于内表数据量较小时.外表返回的每一行都要在内表中检索找到与它匹配的行 ...
- day66_10_10,vue项目环境搭建
一.下载. 首先去官网查看网址. 下载vue环境之前需要先下载node,使用应用商城npm下载,可以将其下载源改成cnpm: """ node ~~ python:nod ...
- [C5W1] Sequence Models - Recurrent Neural Networks
第一周 循环序列模型(Recurrent Neural Networks) 为什么选择序列模型?(Why Sequence Models?) 在本课程中你将学会序列模型,它是深度学习中最令人激动的内容 ...
- Centos7 yum安装MySQL5.7.25
1 下载并安装MySQL官方的 Yum Repository[root@localhost ~]# wget -i -c http://dev.mysql.com/get/mysql57-commun ...
- Python中文注释报错的解决方法
在Python的程序中加了中文注释会报错 解决方法是:在程序的最开始位置加入 # -- coding: utf-8 --
- 与某军工背景软件企业分享Azure DevOps Server的经验
DevOps 是英文单词Development和Operations的组合词,是一种用于促进软件开发.运维实施和质量保障部门之间协同工作的过程和方法. 结合软件开发管理规范,应用自动化的构建.测试和发 ...
- DVWA-文件包含学习笔记
DVWA-文件包含学习笔记 一.文件包含与漏洞 文件包含: 开发人员将相同的函数写入单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写,这种文件调用的过程称文件包含. 文件包含漏洞: 开发人 ...