7

これまで読んだことから、C++ で FFI を使用することは非常に困難です。最大の理由の 1 つは、C++ オブジェクトを Haskell に変換しているようです。私の問題は、C の経験がないことですが、C++ を数年間使用しており、OOP の方が好きです。したがって、私は当然 C++ の恩恵を受けたいと思っています。

Haskell FFI がこれらの問題を回避するために使用するように設計された C++ プログラムを作成できますか? C++ は内部で何でもできますが、API は C に似ています。つまり、オブジェクトを交換したり、最上位関数をオーバーロードしたりしません。注意すべき落とし穴はありますか?

(私のプロジェクトをあなたがよく知っているものと比較するには、SciPy の Weave を使用して Python コードを高速化することを考えてみてください。)

4

1 に答える 1

14

はい、その C++ コードの上に C API を公開する場合、FFI を介して C++ コードを使用できます。

一般的なパターンは、クラスのすべての「メソッド」を C プロシージャとして単純にラップすることです。これにより、そのクラスのオブジェクトを、それらの関数を適用できる不透明なポインターとして扱うことができます。

たとえば、コード ( foo.h) が与えられた場合:

class foo
{
public:
  foo(int a) : _a(a) {}
  ~foo() { _a = 0; } // Not really necessary, just an example

  int get_a() { return _a; }
  void set_a(int a) { _a = a; }

private:
  int _a;
}

...これらすべてのメソッドの C バージョンを簡単に作成できます ( foo_c.h):

#ifdef __cplusplus
typedef foo *foo_ptr;
extern "C"
{
#else
typedef void *foo_ptr;
#endif

foo_ptr foo_ctor(int a);
void foo_dtor(foo_ptr self);

int foo_get_a(foo_ptr self);
void foo_set_a(foo_ptr self, int a);
#ifdef __cplusplus
} /* extern "C" */
#endif

次に、C++ インターフェイスを介して C インターフェイスを実装するアダプター コードが必要です ( foo_c.cpp)。

#include "foo.h"
#include "foo_c.h"

foo_ptr foo_ctor(int a) { return new foo(a); }
void foo_dtor(foo_ptr self) { delete self; }

int foo_get_a(foo_ptr self) { return self->get_a(); }
void foo_set_a(foo_ptr self, int a) { self->set_a(a); }

ヘッダーfoo_c.hを Haskell FFI 定義に含めることができるようになりました。

于 2012-09-18T12:34:37.300 に答える