如何用C语言封装 C++的类(C调用C++函数)、(C++调用C函数)

如何用C语言封装 C++的类(C调用C++函数)、(C++调用C函数)

1、C调用C++

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

//------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;

}

//-----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

//-----test.c

#include "AppleWrapper.h"

#include

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更好:

//-----AppleWrapper.h

#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

//-----AppleWrapper.cpp

#include "AppleWrapper.h"

#include "apple.h"

#include

#ifdef __cplusplus

extern "C" {

#endif

static std::vector 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

2、C++调用C函数实例

// --------------cfun.h

#ifndef __C_FUN_20180228_H__

#define __C_FUN_20180228_H__

#ifdef __cplusplus

extern "C"{

#endif // __cplusplus

void cfun();

#ifdef __cplusplus

}

#endif

#endif

cfun.h头文件中,使用了条件编译#ifdef __cplusplus, 表示如果是C++来调用该接口,则该函数接口经编译后的函数符号生成规则按照C风格走, 否则没有extern "C" , 这样提供的接口同时支持C和C++两者的调用。

// --------------cfun.c

#include "cfun.h"

#include

void cfun()

{

printf("hello world.\n");

}

// --------------main.cpp

#include

#include "cfun.h"

int main()

{

cfun();

system("pause");

return 0;

}

推荐文章

王者荣耀凯一级1000最强铭文出装推荐-凯最强铭文出装一刀一万
36365最新线路检测

王者荣耀凯一级1000最强铭文出装推荐-凯最强铭文出装一刀一万

📅 08-02 👁️‍🗨️ 6171
梅西八夺金球奖辉煌历程:历年排名一览
365bet亚洲

梅西八夺金球奖辉煌历程:历年排名一览

📅 10-01 👁️‍🗨️ 9114
自由幻想结婚流程详细介绍
36365最新线路检测

自由幻想结婚流程详细介绍

📅 07-02 👁️‍🗨️ 9444