为面向对象的 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

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

相关文档推荐

Algorithm to convert RGB to HSV and HSV to RGB in range 0-255 for both(将 RGB 转换为 HSV 并将 HSV 转换为 RGB 的算法,范围为 0-255)
How to convert an enum type variable to a string?(如何将枚举类型变量转换为字符串?)
When to use inline function and when not to use it?(什么时候使用内联函数,什么时候不使用?)
Examples of good gotos in C or C++(C 或 C++ 中好的 goto 示例)
Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);(ios_base::sync_with_stdio(false) 的意义;cin.tie(NULL);)
Is TCHAR still relevant?(TCHAR 仍然相关吗?)