本記事は、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にも答えてあげることを忘れないようにしましょう、ということでもあります。

スポンサード リンク

この記事のカテゴリ

  • ⇒ ISequentialStreamがQIできない