本文给出了一种方法。基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在  wrapper的实现文件里实现。

1. apple.h

  1. #ifndef __APPLE_H__
  2. #define __APPLE_H__
  3. class Apple
  4. {
  5. public:
  6. enum
  7. {
  8. APPLE_COLOR_RED,
  9. APPLE_COLOR_BLUE,
  10. APPLE_COLOR_GREEN,
  11. };
  12. Apple();
  13. int GetColor(void);
  14. void SetColor(int color);
  15. private:
  16. int m_nColor;
  17. };
  18. #endif

apple.cpp:

  1. #include "apple.h"
  2. Apple::Apple():m_nColor(APPLE_COLOR_RED)
  3. {
  4. }
  5. void Apple::SetColor(int color)
  6. {
  7. m_nColor = color;
  8. }
  9. int Apple::GetColor(void)
  10. {
  11. return m_nColor;
  12. }

2. AppleWrapper.h

  1. #ifndef _APPLE_WRAPPER_H__
  2. #define _APPLE_WRAPPER_H_
  3. struct tagApple;
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. struct tagApple *GetInstance(void);
  8. void ReleaseInstance(struct tagApple **ppInstance);
  9. extern void SetColor(struct tagApple *pApple, int color);
  10. extern int GetColor(struct tagApple *pApple);
  11. #ifdef __cplusplus
  12. };
  13. #endif
  14. #endif

AppleWrapper.cpp

  1. #include "AppleWrapper.h"
  2. #include "apple.h"
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. struct tagApple
  7. {
  8. Apple apple;
  9. };
  10. struct tagApple *GetInstance(void)
  11. {
  12. return new struct tagApple;
  13. }
  14. void ReleaseInstance(struct tagApple **ppInstance)
  15. {
  16. delete *ppInstance;
  17. *ppInstance = 0;
  18. }
  19. void SetColor(struct tagApple *pApple, int color)
  20. {
  21. pApple->apple.SetColor(color);
  22. }
  23. int GetColor(struct tagApple *pApple)
  24. {
  25. return pApple->apple.GetColor();
  26. }
  27. #ifdef __cplusplus
  28. };
  29. #endif

3. test.c

  1. #include "AppleWrapper.h"
  2. #include <assert.h>
  3. int main(void)
  4. {
  5. struct tagApple * pApple;
  6. pApple= GetInstance();
  7. SetColor(pApple, 1);
  8. int color = GetColor(pApple);
  9. printf("color = %d\n", color);
  10. ReleaseInstance(&pApple);
  11. assert(pApple == 0);
  12. return 0;
  13. }

可以用 GCC编译:

  1. g++ -c apple.cpp
  2. g++ -c apple.cpp  AppleWrapper.cpp
  3. gcc test.c -o test AppleWrapper.o apple.o -lstdc++

其实,  wrapper里的 struct 完全可以不要,定义一个  handle更好:

  1. #ifndef _APPLE_WRAPPER_H__
  2. #define _APPLE_WRAPPER_H_
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. int  GetInstance(int *handle);
  7. void ReleaseInstance(int *handle);
  8. extern void SetColor(int handle, int color);
  9. extern int GetColor(int handle);
  10. #ifdef __cplusplus
  11. };
  12. #endif
  13. #endif
    1. #include "AppleWrapper.h"
    2. #include "apple.h"
    3. #include <vector>
    4. #ifdef __cplusplus
    5. extern "C" {
    6. #endif
    7. static std::vector<Apple *> g_appleVector;
    8. int GetInstance(int * handle)
    9. {
    10. g_appleVector[0] =  new Apple;
    11. *handle = 0;
    12. return 1;
    13. }
    14. void ReleaseInstance(int *handle)
    15. {
    16. delete g_appleVector[*handle];
    17. *handle = -1;
    18. }
    19. void SetColor(int handle, int color)
    20. {
    21. g_appleVector[handle]->SetColor(color);
    22. }
    23. int GetColor(int handle)
    24. {
    25. return g_appleVector[handle]->GetColor();
    26. }
    27. #ifdef __cplusplus
    28. };
    29. #endif

如何用C语言封装 C++的类,在 C里面使用的更多相关文章

  1. 如何用C#语言构造蜘蛛程序

    "蜘蛛"(Spider)是Internet上一种很有用的程序,搜索引擎利用蜘蛛程序将Web页面收集到数据库,企业利用蜘蛛程序监视竞争对手的网站并跟踪变动,个人用户用蜘蛛程序下载We ...

  2. 使用libzplay库封装一个音频类

    装载请说明原地址,谢谢~~      前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...

  3. 自己封装的CMusic类 【转】

    http://www.cnblogs.com/zhangminaxiang/archive/2013/02/27/2936011.html 缘由: 在改正俄罗斯方块程序的功能的时候,想给这个程序增加一 ...

  4. .NET3.5中JSON用法以及封装JsonUtils工具类

    .NET3.5中JSON用法以及封装JsonUtils工具类  我们讲到JSON的简单使用,现在我们来研究如何进行封装微软提供的JSON基类,达到更加方便.简单.强大且重用性高的效果. 首先创建一个类 ...

  5. MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  7. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

  8. MySQL JDBC事务处理、封装JDBC工具类

    MySQL数据库学习笔记(十)----JDBC事务处理.封装JDBC工具类 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit. ...

  9. DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

    DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类) 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...

随机推荐

  1. c# 添加了按钮双击事件后,再删除掉代码会提示错误

    有两种方法:.清空属性窗口中的双击事件(doubleclick )右边的内容: .单击“发生错误”提示窗口的“否”后,再双击错误列表里的错误项,此时编辑窗口跳转为xx.Designer.cs,然后注释 ...

  2. foreach的2个细节!

    人生不应该在同第一个地方摔第三次.... 1. foreach的时候一定要对要遍历的元素进行null判定. 2. foreach中不要对遍历的元素进行增删改操作(问题严重) 还有一个细节: 使用了的流 ...

  3. Quartz总结(四):动态修改定时器二

    前文:http://www.cnblogs.com/LiuChunfu/p/5598806.html 提到了一种动态修改定时器的方法, 其本质就是在job方法中注入Schedular的对象,从Sche ...

  4. THINKPHP 5.0目录结构

    目录结构 下载最新版框架后,解压缩到web目录下面,可以看到初始的目录结构如下: project 应用部署目录 ├─application 应用目录(可设置) │ ├─common 公共模块目录(可更 ...

  5. STM32开发指南-蜂鸣器实验

    另一种I/O作为输出的应用,利用一个I/O来控制板载的有源蜂鸣器,实现蜂鸣器控制. PS:有源蜂鸣器自带了震荡电路,一通电就会发声:无源蜂鸣器则没有自带震荡电路,必须外部提供2~5Khz左右的方波驱动 ...

  6. 添加<!doctype html>后造成JS写的定位失效

    今天同事找了一个悬浮广告的插件,但是一放入页面中就失效了,也没有报错,后来通过原文件对比,发现是加了<!doctype html>. 这样子定位并不起效果: document.getEle ...

  7. 如何解决找不到方法HttpServletRequest.getServletContext() ---- NoSuchMethodError

    报错 java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getServletContext()Ljavax/serv ...

  8. OpenStack - liberty CentOS 7

    OpenStack私有云部署 Controller Node:       em1(10.6.17.11),em2() Computer Node:         em1(10.6.17.12),e ...

  9. CodeForces 450B Jzzhu and Sequences

    矩阵快速幂. 首先得到公式 然后构造矩阵,用矩阵加速 取模函数需要自己写一下,是数论中的取模. #include<cstdio> #include<cstring> #incl ...

  10. 在线文档转换API word,excel,ppt等在线文件转pdf、png

    在线文档转换API提供word,excel,ppt等在线文件转pdf.png等,文档:https://www.juhe.cn/docs/api/id/259 接口地址:http://v.juhe.cn ...