如何用C语言封装 C++的类,在 C里面使用
本文给出了一种方法。基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在 wrapper的实现文件里实现。
1. apple.h
- #ifndef __APPLE_H__
- #define __APPLE_H__
- class Apple
- {
- public:
- enum
- {
- APPLE_COLOR_RED,
- APPLE_COLOR_BLUE,
- APPLE_COLOR_GREEN,
- };
- Apple();
- int GetColor(void);
- void SetColor(int color);
- private:
- int m_nColor;
- };
- #endif
apple.cpp:
- #include "apple.h"
- Apple::Apple():m_nColor(APPLE_COLOR_RED)
- {
- }
- void Apple::SetColor(int color)
- {
- m_nColor = color;
- }
- int Apple::GetColor(void)
- {
- return m_nColor;
- }
2. AppleWrapper.h
- #ifndef _APPLE_WRAPPER_H__
- #define _APPLE_WRAPPER_H_
- struct tagApple;
- #ifdef __cplusplus
- extern "C" {
- #endif
- struct tagApple *GetInstance(void);
- void ReleaseInstance(struct tagApple **ppInstance);
- extern void SetColor(struct tagApple *pApple, int color);
- extern int GetColor(struct tagApple *pApple);
- #ifdef __cplusplus
- };
- #endif
- #endif
AppleWrapper.cpp
- #include "AppleWrapper.h"
- #include "apple.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- struct tagApple
- {
- Apple apple;
- };
- struct tagApple *GetInstance(void)
- {
- return new struct tagApple;
- }
- void ReleaseInstance(struct tagApple **ppInstance)
- {
- delete *ppInstance;
- *ppInstance = 0;
- }
- void SetColor(struct tagApple *pApple, int color)
- {
- pApple->apple.SetColor(color);
- }
- int GetColor(struct tagApple *pApple)
- {
- return pApple->apple.GetColor();
- }
- #ifdef __cplusplus
- };
- #endif
3. test.c
- #include "AppleWrapper.h"
- #include <assert.h>
- int main(void)
- {
- struct tagApple * pApple;
- pApple= GetInstance();
- SetColor(pApple, 1);
- int color = GetColor(pApple);
- printf("color = %d\n", color);
- ReleaseInstance(&pApple);
- assert(pApple == 0);
- return 0;
- }
可以用 GCC编译:
- g++ -c apple.cpp
- g++ -c apple.cpp AppleWrapper.cpp
- gcc test.c -o test AppleWrapper.o apple.o -lstdc++
其实, wrapper里的 struct 完全可以不要,定义一个 handle更好:
- #ifndef _APPLE_WRAPPER_H__
- #define _APPLE_WRAPPER_H_
- #ifdef __cplusplus
- extern "C" {
- #endif
- int GetInstance(int *handle);
- void ReleaseInstance(int *handle);
- extern void SetColor(int handle, int color);
- extern int GetColor(int handle);
- #ifdef __cplusplus
- };
- #endif
- #endif
- #include "AppleWrapper.h"
- #include "apple.h"
- #include <vector>
- #ifdef __cplusplus
- extern "C" {
- #endif
- static std::vector<Apple *> g_appleVector;
- int GetInstance(int * handle)
- {
- g_appleVector[0] = new Apple;
- *handle = 0;
- return 1;
- }
- void ReleaseInstance(int *handle)
- {
- delete g_appleVector[*handle];
- *handle = -1;
- }
- void SetColor(int handle, int color)
- {
- g_appleVector[handle]->SetColor(color);
- }
- int GetColor(int handle)
- {
- return g_appleVector[handle]->GetColor();
- }
- #ifdef __cplusplus
- };
- #endif
如何用C语言封装 C++的类,在 C里面使用的更多相关文章
- 如何用C#语言构造蜘蛛程序
"蜘蛛"(Spider)是Internet上一种很有用的程序,搜索引擎利用蜘蛛程序将Web页面收集到数据库,企业利用蜘蛛程序监视竞争对手的网站并跟踪变动,个人用户用蜘蛛程序下载We ...
- 使用libzplay库封装一个音频类
装载请说明原地址,谢谢~~ 前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...
- 自己封装的CMusic类 【转】
http://www.cnblogs.com/zhangminaxiang/archive/2013/02/27/2936011.html 缘由: 在改正俄罗斯方块程序的功能的时候,想给这个程序增加一 ...
- .NET3.5中JSON用法以及封装JsonUtils工具类
.NET3.5中JSON用法以及封装JsonUtils工具类 我们讲到JSON的简单使用,现在我们来研究如何进行封装微软提供的JSON基类,达到更加方便.简单.强大且重用性高的效果. 首先创建一个类 ...
- MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JAVA中封装JSONUtils工具类及使用
在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...
- MySQL JDBC事务处理、封装JDBC工具类
MySQL数据库学习笔记(十)----JDBC事务处理.封装JDBC工具类 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit. ...
- DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类) 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...
随机推荐
- 使用response实现文件下载注意点
创建web工程,使用response实现文件的下载. 在webRoot下创建download文件,里面包含要下载的文件,现在把源码贴上来,然后再说我遇到的问题 public class DownLoa ...
- Codeforces Round #369 (Div. 2) D. Directed Roads (DFS)
D. Directed Roads time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- mariadb cache
Since MariaDB Galera cluster versions 5.5.40 and 10.0.14 you can use the query cache. Earlier versio ...
- sencha touch环境搭建
引入touch文件,包括resources和sencha-touch-debug.js文件 index.html文件内容如下: <!DOCTYPE HTML> <html> & ...
- egret dragonbones部件替换产生位移的解决方案
原理:使用Armature.getSlot("urpart").display.texture去替换骨骼纹理即可需要:1 骨骼动画导出的时候不要裁剪部件的透明区域,在导出设置里面设 ...
- 无源RS232转RS485(转)
源:无源RS232转RS485 RS232 -485转换器主要包括了电源.232电平转换.485电路三部分.本电路的232电平转换电路采用了NIH232或者也可以直接使用MAX232集成电路,485 ...
- FastCgi与Cgi
转载请注明出处:http://www.cnblogs.com/stonehat/p/6286966.html 他们之间的不同在于 FastCgi的进程是常驻的,监听一个socket, 无线循 ...
- SQLite Lemon 语法分析器学习与使用
本文是浙江大学出版社的<LEMON语法分析生成器(LALR 1类型)源代码情景分析>学习笔记. 用到的Windows下的编译器介绍MinGW(http://www.mingw.org/): ...
- HYBControllerTransitions中文文档
中文文档 HYBControllerTransitions是自定义围场动画API封装类库,使用简便.使用者不需要了解太多转场动画知识,即可轻松接入项目使用. 这是一个给开发者们提供自定义push.po ...
- CSU 1515 Sequence
莫队算法+map #include<cstdio> #include<cstring> #include<cmath> #include<map> #i ...