C与C++接口相互调用
转载于:http://blog.csdn.net/lincoln_2012/article/details/50801080
项目中经常使用C和C++混合编程,那么,在调用对方接口时,总是不可避免地出现问题。为了让双方和谐地工作,就得用到extern "C"。
1 问题
在C++中,为了支持重载机制,在编译时,要对函数的名字进行一些处理,比如加入函数的返回类型等来加以区别;在C中,只是简单的函数名字而已。如函数void func(int i),C++会把它编译成类似_fun_int或_xxx_funIxxx这样的增加了参数类型的符号,这也是C++可以实现重载的原因;C则把该函数编译成类似_fun的符号,C链接器只要找到该函数符号就可以链接成功,它假设参数类型信息是正确的。故而,关键问题是,C和C++在编译时生成函数名字的方式是不同的。
2 方法
extern "C"是C++的特性,是一种链接约定,它并不影响调用函数的定义,即使做了该声明,对函数类型的检查和参数转换仍要遵循C++的标准,而不是C。主要是为了解决C++在调用C函数库时,用C++直接链接就会出现不能识别符号的问题,而用上extern "C"后,告诉C++编译器要以C语言的方式编译和链接函数,即直接使用函数名而不是一个经过处理的函数名。
3 示例
3.1 C++中调用C接口
代码:
- /***** C头文件c.h *****/
- #ifndef _C_H_
- #define _C_H_
- #ifdef __cplusplus /*C++编译器包含的宏,例如用g++编译时,该宏就存在,则下面的语句extern "C"才会被执行*/
- extern "C" { /*C++编译器才能支持,C编译器不支持*/
- #endif
- void C_fun();
- #ifdef __cplusplus
- }
- #endif
- #endif
- /***** C源文件c.c *****/
- #include "c.h"
- void C_fun()
- {
- /*dosomething*/
- }
- 功能:在文件cpp.cpp中调用文件c.c中的函数C_fun()
- /****** C++源文件cpp.cpp ******/
- #include "c.h"
- int main()
- {
- C_fun()
- }
编译: g++ cpp.cpp c.c
3.2 C中调用C++接口
代码:
- /**** C++头文件 cpp.h *****/
- #ifndef CPP_H
- #define CPP_H
- extern "C" int add( int x, int y );
- #endif
- /**** C++源文件 cpp.cpp *****/
- #include "cpp.h"
- int add( int x, int y )
- {
- return x + y;
- }
- 功能:C文件中调用C++的接口
- /**** C源文件c.c *****/
- extern int add( int x, int y );
- int main( int argc, char* argv[])
- {
- }
编译:gcc c.c cpp.cpp
3.3 C++中调用C库的函数
代码:
- /*C库源文件: hello.c*/
- #include <stdio.h>
- void func()
- {
- printf("hello,world!\n");
- }
编译:gcc --shared -o libhello.so hello.c
- /*C++源文件test.cpp中调用C库的函数*/
- #include <iostream>
- #ifdef __cplusplus
- extern "C" { // 告诉编译器下列代码要以C链接约定的模式进行链接
- #endif
- void func();
- #ifdef __cplusplus
- }
- #endif
- int main()
- {
- func();
- return 0;
- }
编译:g++ test.cpp -o test -lhello
3.4 C中调用C++库的函数
1)C++库代码
- /*C++库源文件hello.cpp*/
- #include <iostream>
- void funcpp()
- {
- std::cout << "hello, world" << std::endl;
- }
编译:g++ --shared -o libhello.so hello.cpp
2)中间接口库,对C++库进行二次封装
- /*中间接口库 mid.cpp*/
- #include <iostream>
- void funcpp();
- #ifdef __cplusplus
- extern "C" { // 即使这是一个C++程序,下列这个函数的实现也要以C约定的风格来搞!
- #endif
- void m_funcpp()
- {
- funcpp();
- }
- #ifdef __cplusplus
- }
- #endi
编译:g++ --shared -o libmid.so mid.cpp -lhello
3)C通过链接二次接口库调用C++库
- /*C源文件test.c*/
- #include <stdio.h>
- int main()
- {
- m_funcpp();
- return 0;
- }
编译:gcc test.c -l mid -o test
转载于:https://www.cnblogs.com/feige1314/p/7890982.html
C与C++接口相互调用相关推荐
- .Net 与 Java 的服务接口相互调用
本文介绍.Net 与 Java 相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 首先说 ...
- android js接口调用方法,详解Android JS相互调用
最近在研究Android.JS相互调用,之前没怎么接触过,只知道loadUrl()就可以加载一个网页了,研究过之后发现Android可以调JS,JS也可以调Android原生控件,很开心啊.下面小编就 ...
- feign调用多个服务_spring cloud各个微服务之间如何相互调用(Feign、Feign带token访问服务接口)...
1.首先先看什么是Feign. 2.若其他服务的接口未做权限处理,参照上文第1点的博文即可. 3.若其他服务的接口做了权限的处理(例如OAuth 2)时该如何访问? a.有做权限处理的服务接口直接调用 ...
- java与js交互,相互调用传参
随着前端技术的发展与H5的广泛使用,移动端采用native+h5的方式越来越多了,对于Android来说就涉及到java与js的交互,相互调用传参等.下面就来看一下java与js交互的简单demo. ...
- JAVA与.NET的相互调用——通过Web服务实现相互调用
JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候 ...
- Python与C之间的相互调用
Python与C之间的相互调用(Python C API及Python ctypes库) 分类: [Python]2010-01-24 17:58 32468人阅读 评论(11) 收藏 举报 pyth ...
- C++和C#相互调用COM组件的方法简介
1.在VS2005中,C#编写DLL并使用C++调用 2.在VS2005中C#编写的COM组件,使用VC6.0调用 3.在VC6.0中编写COM组件,使用VS2005 C#调用 4.在VC6.0 ...
- swift 打包sdk_在封装SDK中Swift和OC混编之相互调用
oc和swift混编之相互调用.jpg 在非SDK中: 1.swift调用oc 步骤: 创建 工程名-Bridging-Header.h 放入oc的头文件,swift即可调用 在swift项目中或者在 ...
- Android JNI学习(五)——Java与Native之间如何实现相互调用
本章将讲述Java与Native之间如何实现相互调用.我将围绕围绕如下三点来讲解. #mermaid-svg-qeVnGlVrLWrB5ryX .label{font-family:'trebuche ...
- unity 热更新:C#与Lua相互调用(转载)
一.基本原理 简单地说,c#调用lua, 是c# 通过Pinvoke方式调用了lua的dll(一个C库),然后这个dll执行了lua脚本. ULua = Lua + LuaJit(解析器.解释器) + ...
最新文章
- OWA登录页面显示为英文而不是中文
- VTK 7.0 安装中内存读取冲突 no override found for “.. 解决记录
- 使用EventViewer记录VSTO add-in启动错误
- 气温常年在25度的地方_最低调的海滨城市,物价便宜,常年25度,沙滩细白,不输三亚!...
- python 太灵活_Python中的灵活参数
- python中numpy.transpose()函数详解
- 基于8086的中断方式4*4矩阵键盘
- Hutool介绍(详)
- java在线测试工具_9个最好用的在线编译/调试工具
- 无刷电机工作及控制原理
- 如何在excel单元格中插入图片批注
- Sp是如何走到这一步
- 谷歌2022学术指标出炉!Nature继续霸榜,CVPR第4,计算机5顶会入Top20
- 图片和文字对齐的方法
- linux 8g内存只认4g,为什么8g运行内存只有4g可用
- PHP模式-单例模式
- 深入学习Java:关于List下标越界源码分析
- 网页头部的声明 lang=zh和 lang=zh-cn 及 lang=zh-cmn的区别
- jdbc之oracle
- 关于dpi、dp与sp的基础了解
热门文章
- 获取用户真实IP以及internalProxies
- k8s学习笔记-环境搭建篇
- mac修改文件的默认打开方式
- ensure函数_vue按需加载组件webpack require.ensure的方法
- 血汗泪计算机音乐,血汗泪 - pikaCinDy_ - 5SING中国原创音乐基地
- 苹果cms模板_我的主题网【第二十五套】精简宽屏大气苹果CMSv10模板DIY系列拆分版...
- 【渝粤教育】广东开放大学 民族音乐概论 形成性考核 (58)
- Building libmesh with Petsc support
- c编程技巧——获取可用的处理器(CPU)核数
- PageHelpe的分页不起作用