はい、その 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 定義に含めることができるようになりました。