如何用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,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...
随机推荐
- PAT (Advanced Level) 1045. Favorite Color Stripe (30)
最长公共子序列变形. #include<iostream> #include<cstring> #include<cmath> #include<algori ...
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom 文中的 Random即:java.util.Random,ThreadLocalRandom 即: ...
- opencart配置mail服务
编辑mail配置,如下图所示 如果sever开启了SSL,则端口改成465 在Contant Us页面留言,发送成功则配置完成
- 基于M9K块配置ROM的LCD12864图片显示实验
先上传三张图片在说 由于串口传输速度较慢,故此实验是在“LCD12864 液晶显示-汉字及自定义显示(并口)”基础上进一步修改而来.在写代码之前 ...
- css hack总结
虽然说,现在讨论css hanck已经过时了,不过了解下还是好的. 各游览器常用兼容标记一览表: 标记 IE6 IE7 IE8 FF Opera Sarari [*+><] √ √ X X ...
- java多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与notify 先看一下java线程运行时各个阶段的运行状态 j ...
- eclipse proxy
-Dorg.eclipse.ecf.provider.filetransfer.excludeContributors=org.eclipse.ecf.provider.filetransfer.ht ...
- Python+Selenium 环境配置之Firefox,IE,Chrome几种浏览器运行
Selenium(Webdriver)支持Firefox,IE,Chrome等多个浏览器.很多人可能装环境时遇到很多问题,下面简单聊聊如何配置测试这几个浏览器以及相关通过简单的实例来测试. 1.Fir ...
- Unity加载本地图片的2种方式
1. 使用 WWW 加载,详细查看 unity3d 官方文档. 2. 使用 System.IO 加载,lua 代码如下: local File = luanet.import_type("S ...
- MFC中PeekMessage的使用,非阻塞消息循环
在程序设计的时候经常要进行一个数据循环,比如播放音乐需要循环的向缓冲区里面写入数据,在这个时候比较通用的方法是建立一个线程做事情,但是有时候不想创建多线程就可以使用微软提供的PeekMessage方法 ...