我正在寻找一套C API,它将围绕我们现有的C++ API来访问我们的核心逻辑(用面向对象C++编写).这将本质上是一个允许我们的C++逻辑可以被其他语言使用的gulp API.什么是一些好的教程、书籍或最佳实践,介绍围绕C语言C++封装C的概念?

推荐答案

这不是很难手工完成,但将取决于您的界面的大小. 在我这样做的情况下,是为了在纯C代码中使用我们的C++库,因此SWIG没有太大帮助.(嗯,也许Sigg可以用来做这件事,但我不是Sigg大师,它看起来不是微不足道的)

我们最后做的就是:

  1. 每个对象都以C语言传递,一个不透明的句柄.
  2. 构造函数和析构函数被包装在纯函数中
  3. 成员函数是纯函数.
  4. 在可能的情况下,其他内置项映射到C类似功能.

这样的类(C++头)

class MyClass
{
  public:
  explicit MyClass( std::string & s );
  ~MyClass();
  int doSomething( int j );
}

将映射到如下C接口(C头):

struct HMyClass; // An opaque type that we'll use as a handle
typedef struct HMyClass HMyClass;
HMyClass * myStruct_create( const char * s );
void myStruct_destroy( HMyClass * v );
int myStruct_doSomething( HMyClass * v, int i );

接口的实现如下所示(C++源代码)

#include "MyClass.h"

extern "C" 
{
  HMyClass * myStruct_create( const char * s )
  {
    return reinterpret_cast<HMyClass*>( new MyClass( s ) );
  }
  void myStruct_destroy( HMyClass * v )
  {
    delete reinterpret_cast<MyClass*>(v);
  }
  int myStruct_doSomething( HMyClass * v, int i )
  {
    return reinterpret_cast<MyClass*>(v)->doSomething(i);
  }
}

我们从原始类派生不透明句柄,以避免需要任何强制转换,(这似乎不适用于我当前的编译器).由于C不支持类,我们必须将句柄设为 struct .

这就给了我们基本的C接口.如果您想要一个更完整的示例来说明集成异常处理的一种方式,那么您可以在GitHub:https://gist.github.com/mikeando/5394166上try 我的代码

有趣的部分是确保您可以将所有需要的C++库正确地链接到大的库中.对于gcc(或clang),这意味着只需使用g++完成最后的链接阶段.

C++相关问答推荐

为指针 struct 创建宏

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

在C中使用动态内存分配找到最小的负数

有没有可能我不能打印?(C,流程)

struct -未知大小

解决S随机内存分配问题,实现跨进程高效数据共享

S将C语言宏定义为自身的目的是什么?(在glibc标题中看到)

S的这种管道实施有什么问题吗?

Caesar密码调试:输出文本末尾的问号和随机字符

错误:字符串在C中获得意外输出

问题:C#Define上的初始值设定项元素不是常量

为什么一个在线编译器拒绝这个VLA代码,而本地的Apple clang却不拒绝;t?

在C中交换字符串和数组的通用交换函数

无法将字符串文字分配给 C 中的字符数组

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

使用替代日历打印日期

使用复合文字数组初始化的指针数组

在带中断的循环缓冲区中使用 易失性

char* 上的 free() 被 valgrind 识别为无效

这种 C 函数风格的名称是什么?