2011-02-03 15 views
2

私はできるだけ簡単に問題を説明します。comコンポーネントの初期化時にコンストラクタを使用する

ここで問題が発生します。

コンストラクタが3つのパラメータを持つコンストラクタを3つ持つcomコンポーネントクラスがあるとします。既にわかっているように、クラスのコンストラクタを呼び出すのではなく、QueryInterfaceを使用してコンポーネントをインスタンス化するので、comクライアントがコンストラクタのパラメータを設定することはできないようです。

大丈夫です、ここに質問があります。

comクライアントが少なくとも2つのパラメータを初期化する必要があるcomコンポーネントをインスタンス化できるようにするには、どのような方法が最適ですか?

答えて

4

オブジェクトインスタンスを直接返す代わりに、QueryInterfaceコールでファクトリを返すことができます。たとえば、代わりの:

あなたはどうなる
// implements IMyClass1 interface 
return new MyClass1(); 

// pointer to member that implements IMyClassFactory interface 
return &m_myClassFactory; 
// this could also be a static class instead of an object instance 

IMyClassFactoryインタフェースはコンストラクタ引数に取り、究極MyClass1インスタンスを返すcreate方法を持っているでしょう。

4

純粋なCOMコンポーネントの場合、これを処理する標準的な方法は、別々のconstuctorsではなくInitialize(foo、bar)メソッドを実装し、COMインスタンス化の直後に呼び出すことです。オブジェクトに適切なデフォルト状態がない場合は、COMオブジェクトのメンバ変数(ポインタ)にすることができます。そのCOMオブジェクトから、Initialize(foo、bar)関数があります。これらの初期化関数のそれぞれで、オブジェクトの正しいバージョンがインスタンス化されます。あなたのCOMラッパーの関数を渡すたびに、あなたのオブジェクトがNULLでないかどうかチェックし、そうであれば適切なHRESULTを返す必要があります。

3

1つのオプションは、ファクトリオブジェクトを使用することです。生成関数はすべて(ステートレスな)ファクトリオブジェクト(もちろん、別のインタフェース上)にあり、実オブジェクトの初期化されたインスタンスを返す。

0

私はAtes Goral'sSteve'sの両方を好きであり、両方を賞賛しています。通常、私はそれを残すだろうが、私はこの時間私は私のフルテイクアウトを綴る必要があると感じる。

これを行うための「ベスト」、「正しい」、「純粋な」、「標準的な」方法は、Atesによって記述されているように、間違いなく工場のパターンです。きれいなAPIを作成したい場合は、その道、が手を下ろしてになります。

しかし、私たちの多くは、商用製品のパブリックAPIを作成することに忙しくはありません。非公開のAPIを使用した小規模な内部プロジェクトの場合、私はその仕事を完了したいだけです。単一のファクトリメソッドを公開できるように余分なオブジェクトを実装することは、むしろ過度の(特にC++の)サウンドになります。実際のケースでは、スティーブの説明のようにInitialize(foo, bar)メソッドを使用します。私は、オブジェクトが初期化されているかどうかを確認するためにすべての重要でないメソッドがチェックされているかどうかを確認し、失敗した場合はHRESULTを返します。

1

私はCOMサーバーを記述するとき、通常、コンポーネントをCoCreateInstanceでインスタンス化することはできません。その代わりに、私はコンストラクタのパラメータを受け入れ、出力パラメータで新しく作成されたオブジェクトへのインターフェイスポインタを返す私のDLLからいくつかの裸の関数(これらはIDLと同様にモジュール内に記述することができます)をエクスポートします。

+0

好奇心。どのようにDCOM/COM +経由でそのようなCOMコンポーネントを使用しますか? – sharptooth

+0

@sharptooth:このようなコンポーネントはインプロセスで使用でき、多くのアプリケーションで有用ですが、決してすべてではありません。 midlがモジュールメンバーの代理人を生成できるかどうかは分かりませんが、決してそれは必要ありません。私は基本的にCOMを、高性能のネイティブ関数へのRADコード(例えばクラシックVB)へのアクセス、および高性能の要求をインプロセスに与えるためのフレンドリーな方法として使用しました。 –

+1

私は参照してください。 MIDLはIDLファイル内のインターフェイスのプロキシのみを生成し、outprocサーバーを(直接またはCOM +サロゲートとして)起動することはできず、これらのエントリ関数のいずれかを保持できません。だからこれはうまくいきません。その作業を行う唯一の方法は、 'CoCreateInstance()'を介して作成できるクラスファクトリを持つことです。 – sharptooth

関連する問題