4

不透明なポインタを次のように公開する(C ++への)レガシーCライブラリインターフェイスを使用しています

typedef void * OpaqueObject

図書館で:

OpaqueObject CreateObject()
{
   return new OurCppLibrary::Object();
}

もちろん、これはこのライブラリのクライアントに型安全性をまったく提供しません。typedefをvoidポインターから構造体ポインターに変更することはまったく同じように機能しますが、少量の型の安全性を提供する必要がありますか?

typedef struct OpaqueObjectInternal_ *OpaqueObject 
// OpaqueObjectInternal_ is NEVER defined anywhere in client or library code

実際には構造体を指していないのに、明示的に構造体を指していますが、アライメントの問題やその他の落とし穴について心配する必要がありますか?

4

3 に答える 3

7

落とし穴はありません。型安全性のために、その形式がまさに好まれます。

いいえ、ここでは位置合わせは問題ではありません。ポインター自体には既知の配置があり、ポインターが指すオブジェクトの配置は、ユーザーではなく、ライブラリの実装にのみ関係します。

于 2011-03-14T21:20:55.713 に答える
2

実際、C++クラスもC構造体です。したがって、これを簡単に行うことができます。

struct Object;
struct Object* Object_Create(void);

そして、ライブラリのCラッパーは次のようになります。

struct Object* Object_Create(void)
{
    return new Object;
}

メソッド呼び出しは次のようになります。

uint32_t Object_DoSomething( struct Object* me, char * text )
{
    return me->DoSomething( text );
}

私はこれを試しましたが、マイナス面は見られません。

于 2012-03-16T20:44:12.863 に答える
1

提案されたコースで最初に考慮すべきことは、作成しているコードを維持しなければならない可能性のある他の人に何を伝えているかです。何よりも不透明なオブジェクトは、ライブラリのユーザーに、ライブラリのメンテナが、文書化された関数でオブジェクトを使用できることを除いて、オブジェクトの実装についてまったく保証しないことを示すCの方法です。ボイド*を取り除くことで、あなたは基本的に世界に「かつては不透明だったこの実装は安定していると宣言します」と発表しています。これはあなたが望むものではないかもしれません。

第二に、あなたが提案しているIMHOは、誰もが幸せにならないような半分の解決策です。より良いアプローチは、ラッパークラスを開発することです。これには、クラスのコンストラクタとデストラクタでCスタイルの不透明なオブジェクトに必然的に付随するinitおよびdestroy関数をラップできるという追加の利点があります。これにより、多くの作業を行うことなく、リソース管理と型安全性をクライアントに提供できます。

于 2011-03-15T09:21:27.337 に答える