5

C++Builder 2010 アプリケーションからいくつかのサード パーティの COM オブジェクトに接続しています。

現在、タイプ ライブラリをインポートしてコンポーネント ラッパーを生成すると、かなり自然な方法でメソッドを呼び出してプロパティにアクセスできるようになります。

object->myProperty = 42;
object->doSomething(666);

ただし、COM オブジェクトのインターフェイス (まだ拡張および開発中) への変更に悩まされており、一部のメソッド GUID が無効になっているように見えるため、独自のアプリが失敗しました。インターフェイスへの唯一の変更が追加であったとしてもです。新しい方法の)。

これに対処する方法として、Late Binding が提案されています。これには、コードを次のように変更する必要があると思います

object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);

明らかに、これは読み書きが面倒なので、代わりにラッパー クラスを作成する必要があります。

タイプ ライブラリをインポートするときに、レイト バインディング ラッパーを自動的に生成する方法はありますか? もしそうなら、それらはオブジェクトが作成されたときに一度だけテキストバインディングを行うほど賢く、メソッド呼び出しごとではありませんか?

4

2 に答える 2

3

遅延バインディングをサポートする COM オブジェクトの TypeLibrary をインポートすると (IDispatchインターフェイスが実装されている場合)、インポーターは静的バインディングと遅延バインディングの両方に対して (コンポーネントではなく) 個別のラッパー クラスを生成できます。

新しいメソッドを既存のインターフェイスに追加しても、コードが無効になることはありません。メソッドには GUID がありません。ただし、IDispatchベースのインターフェイスの場合、そのメソッドにはDISPID関連付けられた値があり、それらのDISPID値はリリースごとに変更できます。立派な COM 開発者は、インターフェイス定義がロックインされると、決してそれを行うべきではありません。

于 2012-07-27T18:44:30.567 に答える
0

TLIBIMP によって生成されたコードとヘッダーを詳細に調査した結果、これはかなり簡単であることがわかりました。

タイプ ライブラリに クラス がある場合、タイプ ライブラリをFooインポートした後、通常は自動生成されたスマート ポインタ クラスを使用しますIFooPtr

{
  IFooPtr f;
  ...
  f->myMethod(1,2);
}

この時点で、バインドは静的であることに注意してください。つまり、オブジェクトの GUID とメソッドの DISPID だけでなく、DLL 内の VTable の正確なレイアウトにも依存します。vtable に影響を与える変更 - たとえば、追加のメソッドを の基本クラスに追加するFooと、メソッド呼び出しが失敗します。

動的バインディングを使用するには、 のIFooDisp代わりに クラスを使用できますIFooPtr。繰り返しますが、これらはスマート ラッパーであり、オブジェクトの有効期間を自動的に処理します。これらのクラス.では、間接->演算子ではなく、演算子を使用してメソッドにアクセスする必要があることに注意してください。間接演算子を使用すると、静的バインディングを介してメソッドが呼び出されます。

{
  IFooDisp f;
  ...
  f.myMethod(1,2);
}

これらのIDispatchベースのラッパーを使用すると、オブジェクトの vtable レイアウトが変更された場合でも、メソッドは DISPID によってディスパッチされます。これらのクラスも、DISPID ではなく関数名でディスパッチする方法を提供していると思いますが、その詳細は確認していません。

于 2013-12-17T23:18:28.617 に答える