IMultiQI
COM公式ドキュメント
IMultiQI (objidlbase.h) インターフェイスを使用すると、クライアントは単一の RPC 呼び出しでオブジェクトのプロキシまたはハンドラーに対して複数のインターフェイスを照会できます。
メソッド 1
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
IMultiQI::QueryMultipleInterfaces (objidlbase.h) メソッドは、オブジェクトがサポートする複数のインターフェイスへのポインターを取得します。
| cMQIs | DWORD | in | pMQIs 配列の要素数。 |
| pMQIs | MULTI_QI* | inout | MULTI_QI 構造体の配列。詳細については「解説」を参照してください。 |
戻り値
このメソッドは次の値を返すことがあります。
| 戻り値 | 説明 |
|---|---|
| 要求されたすべてのインターフェイスへのポインターを取得しました。 | |
| 要求されたインターフェイスの一部(すべてではない)へのポインターを取得しました。 | |
| 要求されたインターフェイスへのポインターを 1 つも取得できませんでした。 |
解説(Remarks)
QueryMultipleInterfaces メソッドは、入力として MULTI_QI 構造体の配列を受け取ります。各構造体はインターフェイスの IID を指定し、インターフェイスポインターと戻り値を受け取るための 2 つの追加メンバーを持ちます。
このメソッドは、できるだけ多くの要求されたインターフェイスポインターをオブジェクトプロキシから直接取得します。プロキシに実装されていない各インターフェイスについては、メソッドはサーバーを呼び出してポインターを取得します。サーバーからインターフェイスポインターを受け取ると、メソッドは対応するインターフェイスプロキシを構築し、そのポインターを、既に実装済みのインターフェイスへのポインターとともに返します。
呼び出し元への注意事項
呼び出し元はまず、オブジェクトプロキシに対して IMultiQI インターフェイスを照会することから始める必要があります。オブジェクトプロキシがこのインターフェイスへのポインターを返した場合、呼び出し元は取得したい各インターフェイスに対して MULTI_QI 構造体を作成する必要があります。各構造体はインターフェイスの IID を指定し、その pItf メンバーを NULL に設定する必要があります。pItf メンバーを NULL に設定しないと、オブジェクトプロキシはその構造体を無視します。戻り時に、QueryMultipleInterfaces は、要求されたインターフェイスポインターと戻り値を、クライアントの配列内の各 MULTI_QI 構造体に書き込みます。pItf メンバーはポインターを受け取り、hr メンバーは戻り値を受け取ります。
QueryMultipleInterfaces の呼び出しから返された値が S_OK の場合、要求されたすべてのインターフェイスに対してポインターが返されています。
戻り値が E_NOINTERFACE の場合、要求されたインターフェイスに対してポインターが 1 つも返されていません。戻り値が S_FALSE の場合、要求された 1 つ以上のインターフェイスへのポインターが返されなかったことを意味します。この場合、クライアントは各 MULTI_QI 構造体の hr メンバーを確認し、どのインターフェイスが取得され、どれが取得されなかったかを判断する必要があります。
クライアントが、あるオブジェクトの複数のインターフェイスを使用することを事前に把握している場合、あらかじめ QueryMultipleInterfaces を呼び出しておくことができます。その後、QueryMultipleInterfaces を通じて既に取得済みのインターフェイスの 1 つに対して QueryInterface が実行されても、RPC 呼び出しは不要になります。
戻り時に、呼び出し元は各 MULTI_QI 構造体の hr メンバーを確認し、どのインターフェイスポインターが返され、どれが返されなかったかを判断する必要があります。
クライアントは、Release を呼び出して、取得した各インターフェイスを解放する責任を負います。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMultiQI "{00000020-0000-0000-C000-000000000046}" #usecom global IMultiQI IID_IMultiQI "{}" #comfunc global IMultiQI_QueryMultipleInterfaces 3 int,var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_IMultiQI "{00000020-0000-0000-C000-000000000046}" #usecom global IMultiQI IID_IMultiQI "{}" #comfunc global IMultiQI_QueryMultipleInterfaces 3 int,sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。