2009-06-29 14 views
7

Cから直接C++オブジェクトを操作する簡単な方法はありますか? いくつかのクラスをC++からCまたはFFI(外部関数インターフェイス)に公開したいと考えています。 確かに、私はそのようなもの書くことができます。C++のコードとオブジェクトはC?

class Foo{ 
.... 
}; 

void *make_foo(...){ 
Foo *ptr = new Foo(..) 

return static_cast<void *>(ptr); 
} 

.. 

int *foo_method1(void *fooptr, ...){ 
Foo *ptr = static_cast<Foo*>(fooptr); 
} 

をしかし、より簡単な方法はありますか?

+0

これはLispと何が関係しているのでしょうか? – Svante

+0

これは、C++クラスをCommon LispにCFFI(またはLisp実装に依存するFFI)に公開するより一般的な質問の一部です。 –

答えて

8

これは一般的に最も簡単な方法です。

また、すべてのCラッパーメソッドでextern "C"を使用する必要があることを覚えておいてください。

7

ほとんどあります。スタンドアローン関数の先頭にextern "C"を付けると、C++コンパイラのname manglingがオフになります。例えば

は:

extern "C" void *make_foo(...){ 
    Foo *ptr = new Foo(..) 

    return static_cast<void *>(ptr); 
} 
1

実際にそれを行うための簡単な方法はありません。 SWIGを使用すると、データの集計以上のユーザー定義型で別の言語に移動できますが、Cに変換するとCのオブジェクトのアイデアを使用する必要があります。

1

Verrazano/Fetterを使用して、C++コードのCFFIバインディングを生成できます。 しかし、それはGCC-XMLを必要とし、私はその移植性についてはわかりません。

1

可能であれば、クラスを構造体から派生させることができます。その後、Cのコードでは、この構造体へのポインタを使用することができます。

// C++ code 
extern "C" struct Cfoo {}; 
extern "C" struct Cbar {}; 

class foo : public Cfoo {}; 
class bar : public Cbar {}; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

それはしかし、gccが、少なくとも異なる種類のポインタ間の変換について警告し、厳密にはエラーではありません。

void foo (void) { 
    struct Cfoo * pf; 
    struct Cbar * pb; 
    pf = pb;  // gcc warns 
} 

あなたは同様のアイデアを使用していますが、Cの構造店にC++オブジェクトへのポインタを持って、その後、継承し、もう一度だけ前進C APIで構造体を宣言することができない場合:

// C++ code 
class foo {}; 
class bar {}; 

extern "C" struct Cfoo { foo * pFoo; }; 
extern "C" struct Cbar { bar * pBar; }; 

// C API 
extern "C" { 
    struct Cfoo; 
    struct Cbar; 
} 

ここでの欠点は、CfooおよびCbarオブジェクトの寿命を考慮する必要があることです。

関連する問題