IUnknown::QueryInterface(REFIID,void**) メソッド (unknwn.h)
COM オブジェクトに対して、インターフェイスの 1 つへのポインターを照会します。インターフェイス識別子 (IID) への参照によってインターフェイスを識別します。 COM オブジェクトが インターフェイスを実装している場合は、そのインターフェイスで IUnknown::AddRef を呼び出した後、そのインターフェイスへのポインターを返します。
構文
HRESULT QueryInterface(
REFIID riid,
void **ppvObject
);
パラメーター
riid
型: REFIID
クエリ対象のインターフェイスのインターフェイス識別子 (IID) への参照。
ppvObject
型: void**
riid パラメーターで指定された IID を持つインターフェイスへのポインターのアドレス。 インターフェイス ポインターのアドレスを渡すので、 メソッドはクエリ対象のインターフェイスへのポインターでそのアドレスを上書きできます。 正常に戻ると、 *ppvObject (逆参照されたアドレス) には、要求されたインターフェイスへのポインターが含まれます。 オブジェクトが インターフェイスをサポートしていない場合、メソッドは *ppvObject (逆参照されたアドレス) を に nullptr
設定します。
戻り値
このメソッドは、インターフェイスがサポートされている場合は S_OK を返し、それ以外の場合は E_NOINTERFACE 返します。 ppvObject (アドレス) が の場合、このメソッドは nullptr
E_POINTERを返します。
注釈
特定の COM オブジェクト (COM コンポーネントとも呼ばれます) の場合、オブジェクトのインターフェイスの IUnknown インターフェイス に対する特定のクエリは、常に同じポインター値を返す必要があります。 これにより、クライアントは、IID_IUnknownを使用して QueryInterface を呼び出し、結果を比較することで、2 つのポインターが同じコンポーネントを指しているかどうかを判断できます。 特に、 IUnknown 以外のインターフェイス (同じポインターを介して同じインターフェイスであっても) に対してクエリを実行すると、同じポインター値が返される必要があるわけではありません。
QueryInterface の実装には 4 つの要件があります (このような場合、"成功する必要があります" は "致命的な失敗を阻止するために成功する必要があります" を意味します)。
- QueryInterface を介してオブジェクトでアクセスできるインターフェイスのセットは、動的ではなく静的である必要があります。 つまり、指定したインターフェイスへのポインターに対する QueryInterface の呼び出しが初めて成功した場合は、もう一度成功する必要があります。 呼び出しが最初に失敗した場合は、後続のすべての呼び出しで失敗する必要があります。
- これは再帰的である必要があります。クライアントがオブジェクト上のインターフェイスへのポインターを保持し、そのインターフェイスに対してクライアントがクエリを実行する場合、呼び出しは成功する必要があります。
- これは対称である必要があります。あるインターフェイスへのポインターを保持しているクライアントが別のインターフェイスに対して正常にクエリを実行した場合、最初のインターフェイスの取得したポインターを介したクエリは成功する必要があります。
- 推移的である必要があります。あるインターフェイスへのポインターを保持しているクライアントが 2 番目のインターフェイスに対して正常にクエリを実行し、そのポインターを介して 3 番目のインターフェイスに対して正常にクエリを実行した場合、3 番目のインターフェイスのポインターを介した最初のインターフェイスのクエリは成功する必要があります。
実装者へのメモ
QueryInterface の実装では、ACL をチェックしないでください。 この規則のメイン理由は、COM では、特定のインターフェイスをサポートするオブジェクトが、そのインターフェイスに対してクエリを実行したときに常に成功を返す必要があるということです。 もう 1 つの理由は、 QueryInterface で ACL をチェックしても、特定のインターフェイスにアクセスできるクライアントは、サーバーへの呼び出しなしで別のクライアントに直接渡すことができるため、実際のセキュリティが提供されないことです。 また、COM はインターフェイス ポインターをキャッシュするため、クライアントがクエリを実行するたびにサーバー上で QueryInterface を呼び出すわけではありません。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows 2000 Professional [デスクトップ アプリのみ] |
サポートされている最小のサーバー | Windows 2000 Server [デスクトップ アプリのみ] |
対象プラットフォーム | Windows |
ヘッダー | unknwn.h |