为面向对象的 C++ 代码开发 C 包装器 API

Developing C wrapper API for Object-Oriented C++ code(为面向对象的 C++ 代码开发 C 包装器 API)
本文介绍了为面向对象的 C++ 代码开发 C 包装器 API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望开发一组 C API,这些 API 将环绕我们现有的 C++ API 以访问我们的核心逻辑(用面向对象的 C++ 编写).这本质上是一个胶水 API,允许我们的 C++ 逻辑被其他语言使用.有哪些好的教程、书籍或最佳实践介绍了将 C 封装在面向对象的 C++ 中所涉及的概念?

I'm looking to develop a set of C APIs that will wrap around our existing C++ APIs to access our core logic (written in object-oriented C++). This will essentially be a glue API that allows our C++ logic to be usable by other languages. What are some good tutorials, books, or best-practices that introduce the concepts involved in wrapping C around object-oriented C++?

推荐答案

这并不难手工完成,但取决于界面的大小.我所做的案例是在纯 C 代码中启用我们的 C++ 库,因此 SWIG 没有太大帮助.(好吧,也许 SWIG 可以用来做到这一点,但我不是 SWIG 大师,这似乎很重要)

This is not too hard to do by hand, but will depend on the size of your interface. The cases where I've done it were to enable use of our C++ library from within pure C code, and thus SWIG was not much help. (Well maybe SWIG can be used to do this, but I'm no SWIG guru and it seemed non-trivial)

我们最终做的就是:

  1. 每个对象都在 C 中传递一个不透明的句柄.
  2. 构造函数和析构函数被包裹在纯函数中
  3. 成员函数是纯函数.
  4. 其他内置函数尽可能映射到 C 等效项.

这样的类(C++ 头文件)

So a class like this (C++ header)

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

将映射到这样的 C 接口(C 头文件):

Would map to a C interface like this (C header):

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++源代码)

The implementation of the interface would look like this (C++ source)

#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 不支持类.

We derive our opaque handle from the original class to avoid needing any casting, and (This didn't seem to work with my current compiler). We have to make the handle a struct as C doesn't support classes.

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

So that gives us the basic C interface. If you want a more complete example showing one way that you can integrate exception handling, then you can try my code on github : https://gist.github.com/mikeando/5394166

现在有趣的部分是确保您将所有必需的 C++ 库正确链接到更大的库中.对于 gcc(或 clang),这意味着只使用 g++ 进行最后的链接阶段.

The fun part is now ensuring that you get all the required C++ libraries linked into you larger library correctly. For gcc (or clang) that means just doing the final link stage using g++.

这篇关于为面向对象的 C++ 代码开发 C 包装器 API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Rising edge interrupt triggering multiple times on STM32 Nucleo(在STM32 Nucleo上多次触发上升沿中断)
How to use va_list correctly in a sequence of wrapper functions calls?(如何在一系列包装函数调用中正确使用 va_list?)
OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?(OpenGL透视投影裁剪多边形,顶点在视锥外=错误的纹理映射?)
How does one properly deserialize a byte array back into an object in C++?(如何正确地将字节数组反序列化回 C++ 中的对象?)
What free tiniest flash file system could you advice for embedded system?(您可以为嵌入式系统推荐什么免费的最小闪存文件系统?)
Volatile member variables vs. volatile object?(易失性成员变量与易失性对象?)