本記事は、COM Advent Calendar 2014 – Qiitaの9日目の記事です。


以前、QueryInterfaceでIStreamが取り出せるがその派生元であるISequentialStreamは取り出せない実装があるらしいという話をしました(ISequentialStreamがQIできない)。そのときは実例を知らなかったのですが、このたび見つけました。MSXMLのDOMDocumentです。

#include <iostream>
#include <windows.h>
#include <comdef.h>
#include <atlbase.h>
#include <atlutil.h>
 
#import <msxml6.dll>
 
template<typename I>
void OutputInterfacePtr(const char* s, const _com_ptr_t<I>& p)
{
  std::cout << s << ": " << static_cast<void*>(p) << std::endl;
}
 
int main()
{
  CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
  try
  {
    MSXML2::IXMLDOMDocumentPtr doc(__uuidof(MSXML2::DOMDocument60));
    if (!doc->loadXML(L"<hoge><piyo/></hoge>"))
    {
      std::clog << "Bad XML!" << std::endl;
      return 1;
    }
 
    IStreamPtr s1 = doc;
    ISequentialStreamPtr s2 = doc;
    OutputInterfacePtr("  IXMLDOMDocument", doc);
    OutputInterfacePtr("          IStream", s1);
    OutputInterfacePtr("ISequentialStream", s2);
  }
  catch (const _com_error& e)
  {
    std::clog << e.ErrorMessage() << std::endl;
  }
  catch (const ATL::CAtlException& e)
  {
    std::clog << ATL::AtlGetErrorDescription(e) << std::endl;
  }
  CoUninitialize();
}

実行結果はこのとおりです。

  IXMLDOMDocument: 027B4A40
          IStream: 027B1810
ISequentialStream: 00000000

くれぐれもIStreamを実装する際には、ISequentialStreamもQueryIntefaceで応答するようにしましょう。

スポンサード リンク

この記事のカテゴリ

  • ⇒ MSXMLはISequentialStreamがQIできない