如何有效解决C与C++的相互调用问题
来源:互联网 发布:国内程序员办公环境 编辑:程序博客网 时间:2024/04/27 16:34
在实际工作中可能经常要进行C和C++的混合编程,C++调用C语言的代码通常都比较容易,但也有一些细节需要注意。C要调用C++的代码就略为麻烦一些,因为C不支持面向对象的特征。
说明:
file TestC.h是C的头文件,file TestC.c是其实现文件,file TestCpp.cpp是调用C函数的C++文件。
文件TestC.h中的TESTC_H定义是为了头文件保护,” #ifdef __cplusplus”这个不能缺少,你可以去查看C的标准库头文件中都有这个,如”stdio.h”。有了这个宏编译器就知道现在是C还是C++在调用它。
为什么要区分C与C++调用呢?其深层次原因是因为C和C++编译器在编译和链接时对于函数的处理不一样。C++为了支持函数重载在编译时会加入函数参数及类型信息。如上面的add方法,C编译器编译后在符号库中的名字为_add,而C++编译器则会产生像_add_int_int之类的名字。C++正是依靠这种机制实现了函数的重载。
将C++类封装为C函数的文件(为了简略也将声明和实现放在了同一个文件中)如下:
实际调用C++代码的C文件如下:
上面的过程很清晰,就是用一个函数将C++类的使用封装起来,然后将它外部声明为C函数就可以了。
文件TestClass.h定义并实现了一个类,该类只有一个add方法。文件TestCpp.cpp定义并实现了一个函数add_cpp,函数中定义了一个HJH类对象并调用了该对象的add方法。然后将add_cpp函数进行外部声明为C。
TestC.c文件中为了使用add_cpp函数,也需要进行外部声明。这是为了通知编译器说明这个函数是在其他文件中实现(注意在C文件中的extern后面不可加”C”)。当这三个文件一起编译链接时,编译器就可以找到add_cpp的具体实现。
1,首先我们来看一下C++调用C语言的代码。要让你的C代码既能被C代码又能被C++调用虽说容易,但是还是有需要注意的地方。现有三个文件分别如下:
/* file TestC.h */#ifndef TESTC_H#define TESTC_H#ifdef __cplusplus//2个下划线extern "C"{#endifint add(int a,int b);#ifdef __cplusplus}#endif#endif
/* TestC.c */#include "TestC.h"int add(int a,int b){return (a+b);}
/* TestCPP.cpp */#include <stdio.h>#include "TestC.h"int main(){printf("add=%d\n",add(2,5));return 0;}
说明:
file TestC.h是C的头文件,file TestC.c是其实现文件,file TestCpp.cpp是调用C函数的C++文件。
文件TestC.h中的TESTC_H定义是为了头文件保护,” #ifdef __cplusplus”这个不能缺少,你可以去查看C的标准库头文件中都有这个,如”stdio.h”。有了这个宏编译器就知道现在是C还是C++在调用它。
为什么要区分C与C++调用呢?其深层次原因是因为C和C++编译器在编译和链接时对于函数的处理不一样。C++为了支持函数重载在编译时会加入函数参数及类型信息。如上面的add方法,C编译器编译后在符号库中的名字为_add,而C++编译器则会产生像_add_int_int之类的名字。C++正是依靠这种机制实现了函数的重载。
extern关键字表示将函数或变量声明为全局类型,与之相对应的是static。static限定函数或变量的作用域为本文件。extern还有一个作用就是与”C”连在一起使用,即extern “C”通知编译器将extern “C”所包含的代码按照C的方式编译和链接。
/* TestClass.h */class ADD{public:int add(int a,int b){return (a+b);}};
将C++类封装为C函数的文件(为了简略也将声明和实现放在了同一个文件中)如下:
/* TestCPP.cpp */#include "TestClass.h"extern "C" int add_cpp(int a,int b);int add_cpp(int a,int b){ADD s;return s.add(a,b) ;}
实际调用C++代码的C文件如下:
/* TestC.c */#include <stdio.h>extern int add_cpp(int a,int b);int main(){printf("add_cpp=%d\n",add_cpp(2,5));return 0;}
上面的过程很清晰,就是用一个函数将C++类的使用封装起来,然后将它外部声明为C函数就可以了。
文件TestClass.h定义并实现了一个类,该类只有一个add方法。文件TestCpp.cpp定义并实现了一个函数add_cpp,函数中定义了一个HJH类对象并调用了该对象的add方法。然后将add_cpp函数进行外部声明为C。
TestC.c文件中为了使用add_cpp函数,也需要进行外部声明。这是为了通知编译器说明这个函数是在其他文件中实现(注意在C文件中的extern后面不可加”C”)。当这三个文件一起编译链接时,编译器就可以找到add_cpp的具体实现。
- 如何有效解决C与C++的相互调用问题
- 如何有效解决C与C++的相互调用问题
- 如何有效解决C与C++的相互调用问题
- 如何有效解决C与C++的相互调用问题
- (转)如何有效解决C与C++的相互调用问题
- C与C++的相互调用问题
- C与C++的相互调用问题
- C语言与汇编语言的相互调用
- C 与 Fortran 的相互调用
- C++与C的相互调用
- C与C++函数的相互调用
- 汇编与c的相互调用
- C/C++与Lua的相互调用
- Python与C之间的相互调用
- C与C++的相互调用
- c/c++如何相互调用
- 【c++】C与C++的相互调用问题&opencv list not found
- perl与c相互调用
- 背景灯常量
- 一张小学二年级的请假条
- Oracle BI Publisher(BIP)生成PDF中文乱码(其他格式显示正常)
- Spring中autowire属性
- Android桌面快捷方式图标生成与删除,使用Intent与launcher交互
- 如何有效解决C与C++的相互调用问题
- 主题:Java中正则表达式的使用
- Jsp学习——filter的使用
- 解决android ListView设置背景后拉动时出现黑色的现象
- DNA序列分类:Fisher判别法
- 身份证号如何校验
- JS实现上传进度条
- 互联网产品中为什么“细节决定成败”。——欢迎补充
- 一个简单的Lucene例子