如何用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 __cplusplusextern "C" {#endifstruct 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 __cplusplusextern "C" {#endifstruct 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 __cplusplusextern "C" {#endifint 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 __cplusplusextern "C" {#endifstatic 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