2017-04-03 17 views
0

別のインターフェイスを返すCOMインターフェイスでメソッドを呼び出すと、毎回punkValが異なります。COMインターフェイスが同じ呼び出しメソッドに対して異なる値を返すのはなぜですか?

しかし、古いpunkValを使用してそのインターフェイスメソッドを呼び出すと、それも機能します。それは不要なオブジェクト(またはおそらくオブジェクトへのポインタ)がたくさん作成されているようですが、返されたインターフェイスが一意であるかどうかを判断するためには幾分か必要です。私が知っているのは、私が呼び出すインターフェイス(punkVal)を返すことであり、その値はすべてのインスタンスごとに異なります。その値が指す値は常に同じですが、vtableまたは何かを指しているため信頼できるチェックではないようです。それは、まったく異なるインターフェースでも、実際は同じインターフェースです。

someCOMInterface foo(); 

私がfooに呼び出し、punkValは私が後で呼び出すためのクエリにそれを呼び出す方法を使用していなければなりませんsomeCOMInterface、あることを期待呼び出し:明確にすることが

。しかし、私が最初の呼び出しを呼び出すたびに、私は別のsomeCOMInterface(呼び出すことによって返される値と同じ "しかし"異なる ")を取得します。

答えて

1

これは珍しいことではありません。同じメソッドへの複数の呼び出しから返されたインターフェイスポインタが同じポインタを返すかどうかは、COMライブラリの開発者によって異なります。

異なるポインタが返される理由の1つは、特定のCOMライブラリ内で使用されるコアオブジェクトモデルがCOMでない可能性があることです。例えば、shared_ptrのようなものを使ってC++でオブジェクトモデルを作成しましたが、これは間違いなくC++クライアントのためのより良いオブジェクトモデルを生成するでしょう。しかし、私のC++オブジェクトモデルを相互運用性のために公開する(またはより一般的にはDLLとして公開する)場合、COMがしばしばより良い選択です。複雑な階層オブジェクトモデルをラッパークラスのセットと同期させて保持することは難しいため、ラッパーオブジェクトは一時的なものになり、必要に応じて作成され、クライアントがもはやそれらを使用しなくなると破棄されます。

このような状況では、クライアントはオブジェクトが「等しい」ことを知る必要があります。つまり、同じ内部オブジェクトをラップする2つの異なるオブジェクトを「等しい」とみなすことができます。これを確認するために、MicrosoftはIObjectEqualityインターフェイスを定義しています。このインターフェイスはCOMラッパークラスによって実装されるので、クライアントが2つの非等価ポインタが概念的に「等しい」オブジェクトであるかどうかを明示的に確認することができます。使用しているオブジェクトは、このインタフェースを実装する場合と実装しない場合があります。 This blog postは、このインタフェースを使用してオブジェクトの等価性を判断する完全な例を示しています。

IObjectEqualityが実装されていない場合、通常は何らかの種類のNameまたはIDまたは他の識別プロパティを指定することによって、COMオブジェクトの開発者がそのような決定を行うための手段を提供します。たとえば、ExcelのApplication.Rangeプロパティは、同じ引数を持つ後続の呼び出しから異なるポインタを返します。 2つの範囲が等しいかどうかを調べるには、Range.Addressメソッドを使用して、その範囲の「識別子」を取得し、それらの識別子を比較することができます。

関連する問題