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


今日はATL::CComGITPtrの使用例です。明日以降、オブジェクトをマーシャリングしたした際の動きについて話していくための前準備でもあります。

このコードはメインスレッドでCoCreateInstanceしたオブジェクトをATL::CComGITPtrで別のスレッドに持って行くだけのプログラムです。簡単にするため、参照キャプチャを使っていますが、本当はC++14ラムダ式でムーブするほうが自然です。

#include <iostream>
#include <future>
#include <thread>
#include <windows.h>
#include <shobjidl.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlutil.h>
 
int f(ATL::CComGITPtr<IUnknown> git)
{
  ATLENSURE_SUCCEEDED(CoInitializeEx(nullptr,
    COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
 
  ATL::CComPtr<IUnknown> u;
  // CopyToメンバ関数でインタフェースへのポインタを取り出せる。
  // 仮引数の型はT**なので、実引数はCComPtrでなくても構わない。
  ATLENSURE_SUCCEEDED(git.CopyTo(&u));
  std::cout << u.p << std::endl;
 
  CoUninitialize();
  return 0;
}
 
int main()
{
  ATLENSURE_RETURN_VAL(
    SUCCEEDED(CoInitializeEx(nullptr,
      COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)),
    -1);
 
  try
  {
    ATL::CComPtr<IUnknown> u;
    ATLENSURE_SUCCEEDED(u.CoCreateInstance(__uuidof(ShellLink), nullptr, CLSCTX_INPROC_SERVER));
    std::cout << u.p << std::endl;
 
    ATL::CComGITPtr<IUnknown> git(u);
    std::packaged_task<int ()> task([&] { return f(std::move(git)); });
    auto result = task.get_future();
    std::thread(std::move(task)).detach();
    result.get();
  }
  catch (const ATL::CAtlException& e)
  {
    std::clog << ATL::AtlGetErrorDescription(e) << std::endl;
  }
  CoUninitialize();
}

出力結果はこんな感じで、このように異なるポインタになります。マーシャリングにより生成されたプロキシオブジェクトを参照しているためです。これはGITだからではなく、ほかの方法でマーシャリングしても同じです。

01328720
0134F620

というわけで、次回はマーシャリングで得たプロキシへのポインタからのメソッド呼び出しを試します。


スポンサード リンク

この記事のカテゴリ

  • ⇒ ATL::CComGITPtrを使ってみる