いくつかのcライブラリをc++でラップすることを検討していますが、不透明なポインタをラップするための最良の方法がわかりません。
C構造体がパブリックAPIの一部である場合
typedef struct _SomeType
{
int a;
int b;
} SomeType_t;
いくつかの「メンバー」機能がある場合:
void SomeTypeFoo( SomeType_t* obj, ... );
void SomeTypeBar( SomeType_t* obj, ... );
これらの「メンバー」関数を実際のクラスメンバーとして単純に関連付けるために、ベースから派生するアプローチが好きです。すなわち:
class SomeTypeWrapper:
public SomeType_t
{
void foo( ... );
void bar( ... );
};
私の理解では、これは、c++メソッドの実装が次のようになるようにキャストできるものSomeTypeWrapper
と「バイナリ互換」であると信じています。struct _SomeType
SomeTypeWrapper*
SomeType_t*
SomeTypeWrapper::foo( ... )
{
SomeTypeFoo( (SomeType_t*)this, ... );
}
注[1]を参照してください。
ただし、一部のライブラリでは、構造の定義を非公開にしたいと考えています(これは、ヘッダー/ APIを変更せずに実装を変更できるようにするためだと思います)。したがって、ヘッダーには次のようなものがあります。
typedef struct _SomeType SomeType_t;
そして、すべての「メンバー」関数はこれらの不透明なポインターを処理します。これらのメソッドをインターフェースに「ラップ」するために、これまでに行ったことは、ポインターを含むクラスを提供することです。
class SomeTypeWrapper
{
private:
SomeType_t* m_data;
public:
SomeTypeWrapper( SomeType_t* data ): m_data(data){}
void foo(...);
void bar(...);
};
これは、そのような不透明なポインターを返すcライブラリ内の関数に対して、そのポインターを運ぶために新しいオブジェクトを割り当てる必要があることを意味します。多くのライブラリではおそらく問題ありませんが、この設計ではラッパーの実装が複雑になり、多くの小さなオブジェクトの割り当てを行う高速なcライブラリの場合、この余分なオブジェクトのオーバーヘッドがパフォーマンスの大幅な低下につながる可能性があります。さらに、基になるオブジェクトは参照カウントされる可能性があるため、場合によっては、SomeWrapperTypeが参照カウントを増やすか、コピーコンストラクターを実装するか、プライベートコンストラクターを使用するかなどを決定する必要があります。
ほとんどの場合、私はより良いインターフェースのためにそのペナルティを喜んで支払いますが、私は他のオプションを探しています。C ++ラッパーライブラリで不透明なCポインタを処理するためのよりクリーンな方法はありますか?関連:c ++ヘッダーにc-libraryヘッダーを含める必要がなく、ラッパーオブジェクトの割り当てを必要としないように、ラッパークラスを実装する良い方法はありますか?
SomeTypeWrapper
注[1]:同じコンパイラが使用され、追加のメンバーがなく、仮想メソッドがない限り、このキャストは安全だと思います。同じコンパイラで、gccによってコンパイルされたc-libraryは、同じgccによってコンパイルされたc++ラッパーで動作すると想定しています。おそらくそれは保証されていませんか?