本記事は、COM Advent Calendar 2014 – Qiitaの4日目の記事です。時空が歪んでいます。
ISequentialStreamをQueryInterfaceするこんな関数を作ったことがあります。
#include <comdef.h> ISequentialStreamPtr QuerySequentialStream(IUnknown* u) { ISequentialStreamPtr s; if (SUCCEEDED(s->QueryInterface(&s))) return s; auto hr = u->QueryInterface(IID_ISteram, reinterpret_cast<void**>(&s)); if (SUCCEEDED(hr)) return s; throw _com_error(hr); } |
まずISequentialStreamでQueryInterfaceして、うまくいけばそれを返し、ダメならIStreamでQueryInterfaceしてみるという関数です。
ISequentialStreamではE_NOINTERFACEを返すくせに、その派生であるIStreamについてはQueryInterfaceできるというオブジェクトが存在するようなのです。幸いにして、まだそういう実装に遭遇したことはありません。
もっとも、ISequentialStreamはあとから追加された痕跡があるので、仕方がない面もあると言えます。IStreamは{0000000C-0000-0000-C000-000000000046}なのに対し、ISequentialStreamは{0C733A30-2A1C-11CE-ADE5-00AA0044773D}だからです。大昔から存在するインタフェースのIIDは、みな{xxxxxxxx-0000-0000-C000-000000000046}ですが、ISequentialStreamのIIDはそうではありません。
なお、IUnknown_GetWindow関数にも同様の苦労が見られます。Remarksに、IOleWindowでQueryInterfaceできないものがあるから、そこから派生しているIShellViewでのQueryInterfaceも試してみる旨が記載されています。
逆の立場で、COMオブジェクトを実装するときには、派生元のインタフェースでのQueryInterfaceにも答えてあげることを忘れないようにしましょう、ということでもあります。
スポンサード リンク |
この記事のカテゴリ
- COM ⇒ ISequentialStreamがQIできない