C代码中如何调用C++ C++中如何调用C
注意这里的C调用C++或者C++调用C意思是.c文件中调用.cpp文件中代码,或者相反。
集成开发环境如VC++6.0或者vs都是以文件后缀来区别当前要编译的是C代码还是C++代码,然后采用响应的编译、调用协议等。
使用extern "C" 主要是因为C编译器编译函数时不带参数的类型信息,只包含函数的符号名字。如
int foo( float x )
C编译器会将此函数编译成类似_foo的符号,C连接器只要找到了调用函数的符号,就认为连接成功。
而C++编译器为了实现函数重载,会在编译时带上函数的参数信息。如它可以把上面的函数编译成类似于_foo_float这样的符号。
所以,C调用C++,使用extern "C"则是告诉编译器依照C的方式来编译封装接口,当然接口函数里面的C++语法还是按C++方式编译。
如:1 普通函数
// C++ Code
extern "C" int foo( int x );
int foo( int x )
{
//...
}
这样,编译器会将foo函数编译成类似_foo符号,而不会编译成类似_foo_int符号
则C可以这样调用C++函数
// C Code
int foo( int x );
void cc( int x )
{
foo( x );
//...
}
2 如果想调用重载的C++函数,则须封装单独的接口共C调用。
如
// C++ Code
void foo( int x );
void foo( float x );
extern "C" void foo_i( int x )
{
foo( x );
}
extern "C" void foo_f( float x )
{
foo( x );
}
则C中可这样调用
// C Code
void foo_i( int x );
void foo_f( float x );
void ccc( int x1, float x2 )
{
foo_i( x1 );
foo_f( x2 );
// ...
}
3 C中想调用C++中的成员函数(包括虚函数),则需要提供一个简单的包装(wrapper)。
例如: // C++ code:
class C
{
...
virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}
然后,你就可以这样调用 C::f():
//C code
double call_C_f(struct C* p, int i);//声明
void ccc(struct C* p, int i)
{
double d=call_C_f(p,i);
...
}
问题:参数struct C* p从哪里来,即怎么在C中定义C++对象,其实上面只是说了思想,真实的c中使用C++类需要把原来的类都封装一下,参看下面的文章
http://blog.csdn.net/caspiansea/article/details/9676153
而C++调用C,extern "C" 的作用是:让C++连接器找调用函数的符号时采用C的方式 如:
// C Code
void foo( int x );
C++这样调用C函数
// C++ Code
extern "C" void foo( int x );
就是让C++连接器能过类似于_foo来查找此函数,而非类似于_foo_int这样的符号。
时常在cpp的代码之中看到这样的代码: 特别是C ++中引入C的头文件,这些C头文件中出现很多如下代码。
#ifdef __cplusplus extern "C" { #endif
//一段代码
#ifdef __cplusplus } #endif
要明白为何使用extern "C",还得从cpp中对函数的重载处理开始说起。在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的.
明白了加入与不加入extern "C"之后对函数名称产生的影响,我们继续我们的讨论:为什么需要使用extern "C"呢?C++之父在设计C++之时,考虑到当时已经存在了大量的C代码,为了支持原来的C代码和已经写好C库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略。
试想这样的情况:一个库文件已经用C写好了而且运行得很良好,这个时候我们需要使用这个库文件,但是我们需要使用C++来写这个新的代码。如果这个代码使用的是C++的方式链接这个C库文件的话,那么就会出现链接错误.
现在我们有了一个C库文件,它的头文件是f.h,产生的lib文件是f.lib,那么我们如果要在C++中使用这个库文件,我们需要这样写:
extern "C" {
#include "f.h"
}
C代码中如何调用C++ C++中如何调用C的更多相关文章
- Java中是否可以调用一个类中的main方法?
前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...
- 项目中Ajax调用ashx页面中的Function的实战
前台页面: 使用几个display=none的空间存储DropdownList中的值,点击Search Button后刷新页面再次给DropdownList赋值使用 <%@ Page Langu ...
- JS中的间歇(周期)调用setInterval()与超时(延迟)调用setTimeout()相关总结
超时调用需要使用window.setTimeout(code,millisec)方法 它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前需要等待多少毫秒).其中第一个参数可以是一个包含JS ...
- Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录: 1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...
- 将PL/SQL代码封装在机灵的包中
将代码封装在机灵的包中 http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13plsql-1872456.html 绝大多数基于 ...
- python中的嵌套类(内部类调用外部类中的方法函数)
在为书中版本是3.X的,但2.X不太支持直接调用. 所以,在PYTHON2.X中,要在内部类中调用外部类的方法,就必须得实例化外部类,然后,传入实例进行调用. 花了我两个小时啊,资料没找到,自己一个一 ...
- 使用反射机制实现jQuery调用ashx类中的指定方法
使用反射机制实现jQuery调用ashx类中的指定方法 近期用asp.net做个小网站,但又不喜欢使用asp.net的服务器端控件,经过一番思量后确定前端采用原始的html.后台采用Linq to ...
- C#中调用HttpWebRequest类中Get/Post请求无故失效的诡异问题
先附代码 /// <summary> /// 客户端Http(GET) /// </summary> /// <param name="strUrl" ...
- thymeleaf模板引擎调用java类中的方法(附源码)
前言 <Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦> 由于开源了项目的缘故,很多使用了My Blog项目的朋友遇到问题也都会联系我去解决 ...
随机推荐
- Java中利用MessageFormat对象实现类似C# string.Format方法格式化
我们在写C#代码的时候常常会使用到string.Format("待格式化字符串{0},{1},....",参数1,参数2,...),来格式化字符串,特别是拼接字符的时候,这种方式使 ...
- [异常] Download interrupted: Connection to https://dl-ssl.google.com refused 安卓SDK下载被拒 3步解决
1.SDK Manager 的 Tools ->Options打开SDK Manager的Settings,选中“Force https://… sources to be fetched us ...
- 找出字符串中第一个不重复的字符(JavaScript实现)
如题~ 此算法仅供参考,小菜基本不懂高深的算法,只能用最朴实的思想去表达. //找出字符串中第一个不重复的字符 // firstUniqueChar("vdctdvc"); --& ...
- Ubuntu 安装配置MySQL,并使用VS的Server Explorer UI界面远程管理MySQL
为安装配置方便,使用root账号登入Ubuntu. step1: 键入下面命令安装MySQL. 过程十分简单.安装过程中只需根据提示输入root账号的密码即可. step2:安装完成后检查MySQL是 ...
- [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上)
最近在使用Python爬取网页内容时,总是遇到JS临时加载.动态获取网页信息的困难.例如爬取CSDN下载资源评论.搜狐图片中的“原图”等,此时尝试学习Phantomjs和CasperJS来解决这个问题 ...
- Lucene
Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎. Lucene的目的是为软件开发人员提供一个简单易 ...
- Java CAS 和ABA问题
独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...
- Atitit..文件上传组件选型and最佳实践总结(2)----断点续传
Atitit..文件上传组件选型and最佳实践总结(2)----断点续传 1. 断点续传的原理 1 2. 如何判断一个插件/控件是否支持断点续传?? 1 3. 常用的组件选型结果::马 1 4. 自定 ...
- Node.js的颠覆者:PHP的Swoole扩展
最近2年Node.js很火,异步与协程是网络开发方面热门的话题.在追求新技术的同时,也应该反思下这里面存在的陷阱.Node.js确实是一门有趣好玩有个性的语言和技术,动态性,全异步回调的方 ...
- jxl 2.6.12 与 jxl 2.3.0 稳定版性能比较
jxl 2.3.0 org.jxls:jxls:2.3.0 org.jxls:jxls-poi:1.0.9 org.jxls:jxls-jexcel:1.0.6 jxls-reader:2.0.2 j ...