{"id":645,"date":"2014-02-17T01:02:20","date_gmt":"2014-02-16T16:02:20","guid":{"rendered":"http:\/\/dev.activebasic.com\/egtra\/?p=645"},"modified":"2015-05-05T23:47:25","modified_gmt":"2015-05-05T14:47:25","slug":"com%e3%81%a7%e5%bc%b1%e5%8f%82%e7%85%a7%e3%82%92%e5%ae%9f%e7%8f%be%e3%81%99%e3%82%8b%ef%bc%88%e3%83%9e%e3%83%ab%e3%83%81%e3%82%b9%e3%83%ac%e3%83%83%e3%83%89%e5%af%be%e5%bf%9c%ef%bc%89","status":"publish","type":"post","link":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/","title":{"rendered":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09"},"content":{"rendered":"<p>\u524d\u56de\uff08<a href=\"\/egtra\/2014\/02\/16\/644\/\">COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b<\/a>\uff09\u306e\u7d9a\u304d\u3067\u5f31\u53c2\u7167\u306e\u5b9f\u88c5\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\u7de8\u3067\u3059\u3002\u4eca\u56de\u306e\u30b3\u30fc\u30c9\u306f\u524d\u56de\u304b\u3089\u304c\u3089\u308a\u3068\u5909\u308f\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306f\u30af\u30e9\u30b9ObjectWithWeakReference\u306b\u3059\u3079\u3066\u307e\u3068\u3081\u307e\u3057\u305f\u3002<\/p>\n<ul>\n<li>\u5bfe\u8c61\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30e1\u30e2\u30ea\u9818\u57df<\/li>\n<li>IWeakReferenceSource\u306e\u5b9f\u88c5<\/li>\n<li>IWeakReference\u306e\u5b9f\u88c5<\/li>\n<\/ul>\n<section>\n<h3>\u5bfe\u8c61\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/h3>\n<p>\u5bfe\u8c61\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306fATL::CComContainedObject\u3092\u4f7f\u3044\u3001aligned_storage\u3067\u78ba\u4fdd\u3057\u305f\u9818\u57df\u306b\u69cb\u7bc9\u3055\u305b\u3066\u3044\u307e\u3059\u3002C++11\u306eunion\u304c\u4f7f\u3048\u308c\u3070\u3088\u3044\u306e\u3067\u3059\u304c\u3001Visual C++\u306b\u306f\u307e\u3060\u3042\u308a\u307e\u305b\u3093\u3002<\/p>\n<pre lang=\"cpp\">\r\ntypedef ATL::CComContainedObject<T> Obj;\r\ntypename std::aligned_storage<\r\n  sizeof (Obj), std::alignment_of<Obj>::value>::type m_contained;\r\n<\/pre>\n<p>m_contained\u4e0a\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306fObjectWithWeakReference\u306e\u30b3\u30f3\u30b9\u30c8\u30e9\u30af\u30bf\u3067\u69cb\u7bc9\u3057\u307e\u3059\u3002\u305d\u3057\u3066m_strongRef\u304c0\u306b\u306a\u3063\u305f\u3089\u7834\u68c4\u3057\u307e\u3059\u3002<\/p>\n<pre lang=\"cpp\">\r\nstd::atomic<ULONG> m_strongRef = 1;\r\n\r\nObjectWithWeakReference()\r\n{\r\n  ::new(&m_contained) Obj(\r\n    static_cast<IUnknown*>(GetWeakReferenceSource()));\r\n}\r\n\r\nSTDMETHOD_(ULONG, ObjectRelease)() override\r\n{\r\n  auto p = GetContainedObject();\r\n  auto c = --m_strongRef;\r\n  if (c == 0)\r\n  {\r\n    p->FinalRelease();\r\n    p->~Obj();\r\n\r\n    \/\/ FinalConstruct\u3067InternalAddRef\u3057\u305f\u3082\u306e\u306b\u5bfe\u5fdc\u3059\u308b\u3002\r\n    InternalRelease();\r\n  }\r\n  return c;\r\n}\r\n\r\nObj* GetContainedObject()\r\n{\r\n  assert(m_strongRef > 0);\r\n  return reinterpret_cast<Obj*>(&m_contained);\r\n}\r\n<\/pre>\n<p>GetWeakReferenceSource()\u306f\u5c0f\u7d30\u5de5\u5165\u308a\u306e\u30a2\u30c3\u30d7\u30ad\u30e3\u30b9\u30c8\u3067\u3001IWeakReferenceSource*\u3092\u8fd4\u3057\u307e\u3059\u3002<\/p>\n<p>\u306a\u304a\u3001\u3053\u306eObjectWithWeakReference\u3067\u306f\u3001\u5f37\u53c2\u7167\u304c\u306a\u304f\u306a\u3063\u3066\u3082\u5f31\u53c2\u7167\u304c\u306a\u304f\u306a\u308b\u307e\u3067\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u5927\u304d\u3055\u5206\u30e1\u30e2\u30ea\u3092\u5360\u6709\u3057\u7d9a\u3051\u307e\u3059\u3002\u3053\u3046\u3057\u305f\u7406\u7531\u306f\u3001\u5f31\u53c2\u7167\u3092\u9577\u671f\u9593\u653e\u7f6e\u3059\u308b\u3088\u3046\u306a\u4f7f\u3044\u65b9\u306f\u5e0c\u3060\u308d\u3046\u3068\u5224\u65ad\u3057\u305f\u305f\u3081\u3067\u3059\u3002\u3061\u306a\u307f\u306b\u3001boost::make_shared\u3082\u540c\u3058\u6319\u52d5\u3067\u3059\u3002<\/p>\n<h3>IWeakReferenceSource<\/h3>\n<p>VTable\u306e\u9806\u756a\u3055\u3048\u3042\u3063\u3066\u3044\u308c\u3070OK\u3001\u3068\u3044\u3046\u306e\u304cCOM\u3067\u3059\u3002IUnknown\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u5225\u540d\u306b\u3057\u305fIWeakReferenceSourceImpl\u304b\u3089\u6d3e\u751f\u3055\u305b\u308b\u3053\u3068\u3067\u3001\u5f31\u53c2\u7167\u7528\u306eIUnknown\u3068\u5f37\u53c2\u7167\u7528\u306eIUnknown\u30921\u30af\u30e9\u30b9\u306b\u5171\u5b58\u3055\u305b\u3066\u3044\u307e\u3059\u3002C++\u7684\u306b\u7dba\u9e97\u306a\u5b9f\u88c5\u65b9\u6cd5\u3082\u3042\u308b\u306e\u3067\u3059\u304c\u3001\u3053\u306e\u307b\u3046\u304c\u7c21\u5358\u306a\u306e\u3067\u3059\u3002<\/p>\n<p>\u3053\u306e\u624b\u6cd5\u306fATL\u3067\u3082_IDispEvent::_LocDEQueryInterface\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre lang=\"cpp\">\r\nclass DECLSPEC_NOVTABLE IWeakReferenceSourceImpl\r\n{\r\npublic:\r\n  STDMETHOD(ObjectQueryInterface)(\r\n    _In_ REFIID riid, _COM_Outptr_ void** ppv) = 0;\r\n  STDMETHOD_(ULONG, ObjectAddRef)() = 0;\r\n  STDMETHOD_(ULONG, ObjectRelease)() = 0;\r\n  STDMETHOD(GetWeakReference)(\r\n    _COM_Outptr_ egtra::IWeakReference** weakReference) = 0;\r\n};\r\n\r\ntemplate<class T>\r\nclass ObjectWithWeakReference\r\n  : public ATL::CComObjectRootEx<ATL::CComMultiThreadModelNoCS>\r\n  , public egtra::IWeakReference\r\n  , public IWeakReferenceSourceImpl\r\n{\r\npublic:\r\n  virtual HRESULT STDMETHODCALLTYPE GetWeakReference(\r\n    \/* [retval][out] *\/ _COM_Outptr_ egtra::IWeakReference** weakReference\r\n    ) throw() override\r\n  {\r\n    ATLENSURE_RETURN_HR(weakReference != nullptr, E_POINTER);\r\n    *weakReference = this;\r\n    AddRef();\r\n    return S_OK;\r\n  }\r\n\r\n  egtra::IWeakReferenceSource* GetWeakReferenceSource()\r\n  {\r\n    return reinterpret_cast<egtra::IWeakReferenceSource*>(\r\n      static_cast<IWeakReferenceSourceImpl*>(this));\r\n  }\r\n<\/pre>\n<h3>IWeakReference<\/h3>\n<p>Resolve\u30e1\u30bd\u30c3\u30c9\u3067\u306f\u3001\u5f37\u53c2\u7167\u306e\u30ab\u30a6\u30f3\u30bf\u3092\u898b\u3066\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u8fd4\u3057\u3066\u826f\u3044\u304b\u5224\u5b9a\u3057\u3066\u3044\u307e\u3059\u30021\u30af\u30e9\u30b9\u306b\u307e\u3068\u3081\u3066\u5b9f\u88c5\u3057\u305f\u7406\u7531\u3082\u3053\u3053\u306b\u3042\u308a\u3001\u3059\u306a\u308f\u3061\u5f37\u53c2\u7167\u306e\u30ab\u30a6\u30f3\u30bf\u3092\u8aad\u307f\u66f8\u304d\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308b\u304b\u3089\u3067\u3059\u3002<\/p>\n<pre lang=\"cpp\">\r\nvirtual HRESULT STDMETHODCALLTYPE Resolve(\r\n  \/* [in] *\/ _In_ REFIID riid,\r\n  \/* [iid_is][out] *\/ _COM_Outptr_result_maybenull_ void** ppv\r\n  ) throw() override\r\n{\r\n  ATLENSURE_RETURN_HR(ppv != nullptr, E_POINTER);\r\n  *ppv = nullptr;\r\n  if (!TryAddRef())\r\n  {\r\n    return S_FALSE;\r\n  }\r\n  auto hr = ObjectQueryInterface(riid, ppv);\r\n  ObjectRelease(); \/\/ TryAddRef\u306e\u5206\r\n  return hr;\r\n}\r\n\r\nbool TryAddRef()\r\n{\r\n  for (;;)\r\n  {\r\n    auto c = m_strongRef.load(std::memory_order_relaxed);\r\n    if (c == 0)\r\n    {\r\n      return false;\r\n    }\r\n    if (m_strongRef.compare_exchange_weak(\r\n      c, c + 1, std::memory_order_relaxed))\r\n    {\r\n      return true;\r\n    }\r\n    _mm_pause();\r\n  }\r\n}\r\n<\/pre>\n<h3>\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9<\/h3>\n<p>\u4ee5\u4e0b\u3001\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u5168\u4f53\u3067\u3059\u3002\u53c2\u7167\u30ab\u30a6\u30f3\u30c8\u306b\u5bfe\u3057\u3066\u3001\u7a4d\u6975\u7684\u306bmemory_order_relaxed\u3092\u4f7f\u3063\u3066\u307f\u307e\u3057\u305f\u3002<\/p>\n<pre lang=\"cpp\">\r\n#include <atomic>\r\n#include <iostream>\r\n#include <memory>\r\n#include <cassert>\r\n#include <intrin.h>\r\n#include <atlbase.h>\r\n#include <atlcom.h>\r\n\r\nclass Module : public ATL::CAtlExeModuleT<Module> {};\r\nModule module;\r\n\r\nnamespace egtra\r\n{\r\n  MIDL_INTERFACE(\"bdcb7ca6-376d-481a-8652-dfd69f723ecc\")\r\n  IWeakReference : IUnknown\r\n  {\r\n  public:\r\n    virtual HRESULT STDMETHODCALLTYPE Resolve(\r\n      \/* [in] *\/ __RPC__in REFIID riid,\r\n      \/* [iid_is][out] *\/ __RPC__deref_out void** objectReference) = 0;\r\n  };\r\n\r\n  MIDL_INTERFACE(\"de2988fe-a6b7-4e3d-923e-7463ce0e1040\")\r\n  IWeakReferenceSource : IUnknown\r\n  {\r\n  public:\r\n    virtual HRESULT STDMETHODCALLTYPE GetWeakReference(\r\n      \/* [retval][out] *\/ __RPC__deref_out IWeakReference** weakReference\r\n      ) = 0;\r\n  };\r\n}\r\n\r\ntemplate<typename T>\r\nATL::CComPtr<T> CreateComObject()\r\n{\r\n  auto p = std::make_unique<ATL::CComObject<T>>();\r\n  p->SetVoid(nullptr);\r\n  p->InternalFinalConstructAddRef();\r\n  HRESULT hRes = p->_AtlInitialConstruct();\r\n  if (SUCCEEDED(hRes))\r\n    hRes = p->FinalConstruct();\r\n  if (SUCCEEDED(hRes))\r\n    hRes = p->_AtlFinalConstruct();\r\n  p->InternalFinalConstructRelease();\r\n  return hRes == S_OK\r\n    ? p.release()\r\n    : nullptr;\r\n}\r\n\r\nclass DECLSPEC_NOVTABLE IWeakReferenceSourceImpl\r\n{\r\npublic:\r\n  STDMETHOD(ObjectQueryInterface)(\r\n    _In_ REFIID riid, _COM_Outptr_ void** ppv) = 0;\r\n  STDMETHOD_(ULONG, ObjectAddRef)() = 0;\r\n  STDMETHOD_(ULONG, ObjectRelease)() = 0;\r\n  STDMETHOD(GetWeakReference)(\r\n    _COM_Outptr_ egtra::IWeakReference** weakReference) = 0;\r\n};\r\n\r\ntemplate<class T>\r\nclass ObjectWithWeakReference\r\n  : public ATL::CComObjectRootEx<ATL::CComMultiThreadModelNoCS>\r\n  , public egtra::IWeakReference\r\n  , public IWeakReferenceSourceImpl\r\n{\r\n  typedef ATL::CComContainedObject<T> Obj;\r\n\r\n  BEGIN_COM_MAP(ObjectWithWeakReference)\r\n    COM_INTERFACE_ENTRY(egtra::IWeakReference)\r\n  END_COM_MAP()\r\n\r\npublic:\r\n  DECLARE_PROTECT_FINAL_CONSTRUCT()\r\n\r\n  ObjectWithWeakReference()\r\n  {\r\n    ::new(&m_contained) Obj(\r\n      static_cast<IUnknown*>(GetWeakReferenceSource()));\r\n  }\r\n\r\n  HRESULT _AtlInitialConstruct()\r\n  {\r\n    HRESULT hr = GetContainedObject()->_AtlInitialConstruct();\r\n    ATLENSURE_RETURN_HR(SUCCEEDED(hr), hr);\r\n    return __super::_AtlInitialConstruct();\r\n  }\r\n\r\n  HRESULT FinalConstruct()\r\n  {\r\n    InternalAddRef();\r\n    auto hr = __super::FinalConstruct();\r\n    ATLENSURE_RETURN_HR(SUCCEEDED(hr), hr);\r\n    return GetContainedObject()->FinalConstruct();\r\n  }\r\n\r\n  void FinalRelease()\r\n  {\r\n    auto c = m_strongRef.load(std::memory_order_relaxed);\r\n    assert(c == 0 || c == 1);\r\n    if (c == 1)\r\n    {\r\n      ObjectRelease();\r\n    }\r\n    __super::FinalRelease();\r\n  }\r\n\r\n  virtual HRESULT STDMETHODCALLTYPE ObjectQueryInterface(\r\n    _In_ REFIID riid, _COM_Outptr_ void** ppv) throw() override\r\n  {\r\n    ATLENSURE_RETURN_HR(ppv != nullptr, E_POINTER);\r\n    if (riid == __uuidof(egtra::IWeakReferenceSource))\r\n    {\r\n      *ppv = GetWeakReferenceSource();\r\n      ObjectAddRef();\r\n      return S_OK;\r\n    }\r\n    return GetContainedObject()->_InternalQueryInterface(riid, ppv);\r\n  }\r\n\r\n  virtual ULONG STDMETHODCALLTYPE ObjectAddRef() throw() override\r\n  {\r\n    \/\/ \u7c21\u5358\u306b\u3059\u308b\u305f\u3081\u30a4\u30f3\u30af\u30ea\u30e1\u30f3\u30c8\u524d\u306e\u5024\u3092\u305d\u306e\u307e\u307e\u8fd4\u3059\u3002\r\n    return m_strongRef.fetch_add(1, std::memory_order_relaxed);\r\n  }\r\n\r\n  virtual ULONG STDMETHODCALLTYPE ObjectRelease() throw() override\r\n  {\r\n    auto p = GetContainedObject();\r\n    \/\/ FinalRelease\u524d\u306b\u306fmemory_order_seq_cst\u3092\u5165\u308c\u3088\u3046\u3068\u601d\u3044\u3001\r\n    \/\/ \u30c7\u30af\u30ea\u30e1\u30f3\u30c8\u6f14\u7b97\u5b50\u3092\u4f7f\u7528\u3057\u305f\u3002\r\n    auto c = --m_strongRef;\r\n    if (c == 0)\r\n    {\r\n      \/\/ \u4e0a\u8a18\u3092memory_order_relaxed\u306b\u3057\u3066\r\n      \/\/ \u3053\u3053\u3067std::atomic_thread_fence(std::memory_order_seq_cst)\r\n      \/\/ \u3068\u3044\u3046\u624b\u3082\u3042\u308b\u304c\u3001\u30b3\u30fc\u30c9\u304c\u8907\u96d1\u306b\u306a\u308b\u306e\u3067\u63a1\u7528\u3057\u306a\u304b\u3063\u305f\u3002\r\n      p->FinalRelease();\r\n      p->~Obj();\r\n      InternalRelease();\r\n    }\r\n    return c;\r\n  }\r\n\r\n  virtual HRESULT STDMETHODCALLTYPE GetWeakReference(\r\n    \/* [retval][out] *\/ _COM_Outptr_ egtra::IWeakReference** weakReference\r\n    ) throw() override\r\n  {\r\n    ATLENSURE_RETURN_HR(weakReference != nullptr, E_POINTER);\r\n    *weakReference = this;\r\n    AddRef();\r\n    return S_OK;\r\n  }\r\n\r\n  virtual HRESULT STDMETHODCALLTYPE Resolve(\r\n    \/* [in] *\/ _In_ REFIID riid,\r\n    \/* [iid_is][out] *\/ _COM_Outptr_result_maybenull_ void** ppv\r\n    ) throw() override\r\n  {\r\n    ATLENSURE_RETURN_HR(ppv != nullptr, E_POINTER);\r\n    *ppv = nullptr;\r\n    if (!TryAddRef())\r\n    {\r\n      return S_FALSE;\r\n    }\r\n    auto hr = ObjectQueryInterface(riid, ppv);\r\n    ObjectRelease(); \/\/ TryAddRef\u306e\u5206\r\n    return hr;\r\n  }\r\n\r\n  Obj* GetContainedObject()\r\n  {\r\n    assert(m_strongRef > 0);\r\n    return reinterpret_cast<Obj*>(&m_contained);\r\n  }\r\n\r\nprivate:\r\n  bool TryAddRef()\r\n  {\r\n    for (;;)\r\n    {\r\n      auto c = m_strongRef.load(std::memory_order_relaxed);\r\n      if (c == 0)\r\n      {\r\n        return false;\r\n      }\r\n      if (m_strongRef.compare_exchange_weak(\r\n        c, c + 1, std::memory_order_relaxed))\r\n      {\r\n        return true;\r\n      }\r\n      _mm_pause();\r\n    }\r\n  }\r\n\r\n  egtra::IWeakReferenceSource* GetWeakReferenceSource()\r\n  {\r\n    return reinterpret_cast<egtra::IWeakReferenceSource*>(\r\n      static_cast<IWeakReferenceSourceImpl*>(this));\r\n  }\r\n\r\n  typename std::aligned_storage<\r\n    sizeof (Obj), std::alignment_of<Obj>::value>::type m_contained;\r\n  std::atomic<ULONG> m_strongRef = 1;\r\n};\r\n\r\ntemplate<typename T>\r\nATL::CComPtr<T> CreateComObjectWithWeakRef()\r\n{\r\n  if (auto weak = CreateComObject<ObjectWithWeakReference<T>>())\r\n  {\r\n    ATL::CComPtr<T> obj;\r\n    obj.Attach(weak->GetContainedObject());\r\n    return obj;\r\n  }\r\n  else\r\n  {\r\n    return nullptr;\r\n  }\r\n}\r\n\r\nMIDL_INTERFACE(\"0f9a78ce-4f58-4160-9889-e3bd4485c92d\") ITest : IUnknown\r\n{\r\n  virtual HRESULT STDMETHODCALLTYPE Test() = 0;\r\n};\r\n\r\nclass ATL_NO_VTABLE TestImpl\r\n  : public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>\r\n  , public ITest\r\n{\r\n  DECLARE_NOT_AGGREGATABLE(TestImpl)\r\n\r\n  BEGIN_COM_MAP(TestImpl)\r\n    COM_INTERFACE_ENTRY(ITest)\r\n  END_COM_MAP()\r\n\r\npublic:\r\n  HRESULT FinalConstruct() throw()\r\n  {\r\n    std::cout << \"TestImpl::FinalConstruct\" << std::endl;\r\n    return S_OK;\r\n  }\r\n\r\n  HRESULT FinalRelease() throw()\r\n  {\r\n    std::cout << \"TestImpl::FinalRelease\" << std::endl;\r\n    return S_OK;\r\n  }\r\n\r\n  virtual HRESULT STDMETHODCALLTYPE Test() throw() override\r\n  {\r\n    std::cout << \"TestImpl::Test\" << std::endl;\r\n    return S_OK;\r\n  }\r\n\r\n  void Test2()\r\n  {\r\n    std::cout << \"TestImpl::Test2 (non-virtual)\" << std::endl;\r\n  }\r\n};\r\n\r\nint main()\r\n{\r\n  ATL::CComPtr<egtra::IWeakReference> weak;\r\n  {\r\n    auto x = CreateComObjectWithWeakRef<TestImpl>();\r\n    ATL::CComQIPtr<egtra::IWeakReferenceSource> s(x);\r\n    ATLENSURE_SUCCEEDED(s->GetWeakReference(&weak));\r\n\r\n    ATL::CComPtr<IUnknown> u;\r\n    weak->Resolve(IID_PPV_ARGS(&u));\r\n    std::cout << static_cast<IUnknown*>(u) << std::endl;\r\n  }\r\n\r\n  ATL::CComPtr<IUnknown> u;\r\n  weak->Resolve(IID_PPV_ARGS(&u));\r\n  std::cout << static_cast<IUnknown*>(u) << std::endl;\r\n}\r\n<\/pre>\n<p>\u5229\u7528\u4f8b\uff08main\u95a2\u6570\uff09\u304c\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306a\u611f\u3058\u306b\u306a\u3063\u3066\u3044\u306a\u3044\u306e\u306f\u7533\u3057\u8a33\u3042\u308a\u307e\u305b\u3093\u3002<\/p>\n<\/section>\n<p>\u3053\u308c\u3092\u5b9f\u73fe\u3059\u308b\u306b\u5f53\u305f\u3063\u3066\u3001boost::shared_ptr\u3068libc++\u306estd::shared_ptr\u306e\u30bd\u30fc\u30b9\u3092\u53c2\u8003\u306b\u3057\u307e\u3057\u305f\u3002\u5f37\u53c2\u7167\u304c\u751f\u304d\u3066\u3044\u308b\u9593\u3001\u5f31\u53c2\u7167\u306e\u30ab\u30a6\u30f3\u30c8\u3092+1\u3057\u3066\u304a\u304f\u3053\u3068\u3084\u3001\u5f31\u53c2\u7167\u304b\u3089\u5f37\u53c2\u7167\u3092\u5f97\u308b\u969b\u306eCAS\u306a\u3069\u306f\u305d\u3053\u304b\u3089\u7740\u60f3\u3092\u5f97\u307e\u3057\u305f\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[5,10,12],"tags":[142,50,81,282],"class_list":["post-645","post","type-post","status-publish","format-standard","hentry","category-cpp","category-com","category-vc","tag-atl","tag-cplusplus11","tag-atomic-operation","tag-weak-reference"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d<\/title>\n<meta name=\"description\" content=\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/\" \/>\n<meta property=\"og:locale\" content=\"ja_JP\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d\" \/>\n<meta property=\"og:description\" content=\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/\" \/>\n<meta property=\"og:site_name\" content=\"\u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ysk.noh\" \/>\n<meta property=\"article:published_time\" content=\"2014-02-16T16:02:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-05-05T14:47:25+00:00\" \/>\n<meta name=\"author\" content=\"egtra\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@egtra\" \/>\n<meta name=\"twitter:site\" content=\"@egtra\" \/>\n<meta name=\"twitter:label1\" content=\"\u57f7\u7b46\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"egtra\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"4\u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/\",\"url\":\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/\",\"name\":\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d\",\"isPartOf\":{\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/#website\"},\"datePublished\":\"2014-02-16T16:02:20+00:00\",\"dateModified\":\"2015-05-05T14:47:25+00:00\",\"author\":{\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/#\/schema\/person\/8de756b2ff20b964f64594dfe8f18164\"},\"description\":\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002\",\"breadcrumb\":{\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/#breadcrumb\"},\"inLanguage\":\"ja\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u30db\u30fc\u30e0\",\"item\":\"https:\/\/dev.activebasic.com\/egtra\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/#website\",\"url\":\"https:\/\/dev.activebasic.com\/egtra\/\",\"name\":\"\u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d\",\"description\":\"\u982d\u306e\u4e2d\u306e\u304b\u3051\u3089\u3002ActiveBasic\u3092\u4e2d\u5fc3\u306b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u306e\u8a71\u3092\u307c\u3061\u307c\u3061\u3068\u3002\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/dev.activebasic.com\/egtra\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"ja\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/dev.activebasic.com\/egtra\/#\/schema\/person\/8de756b2ff20b964f64594dfe8f18164\",\"name\":\"egtra\",\"sameAs\":[\"https:\/\/x.com\/egtra\"],\"url\":\"https:\/\/dev.activebasic.com\/egtra\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d","description":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/","og_locale":"ja_JP","og_type":"article","og_title":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d","og_description":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002","og_url":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/","og_site_name":"\u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d","article_publisher":"https:\/\/www.facebook.com\/ysk.noh","article_published_time":"2014-02-16T16:02:20+00:00","article_modified_time":"2015-05-05T14:47:25+00:00","author":"egtra","twitter_card":"summary_large_image","twitter_creator":"@egtra","twitter_site":"@egtra","twitter_misc":{"\u57f7\u7b46\u8005":"egtra","\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593":"4\u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/","url":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/","name":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09 - \u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d","isPartOf":{"@id":"https:\/\/dev.activebasic.com\/egtra\/#website"},"datePublished":"2014-02-16T16:02:20+00:00","dateModified":"2015-05-05T14:47:25+00:00","author":{"@id":"https:\/\/dev.activebasic.com\/egtra\/#\/schema\/person\/8de756b2ff20b964f64594dfe8f18164"},"description":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\u8a66\u307f\u306e\u7d9a\u304d\u3001\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u306b\u5bfe\u5fdc\u3057\u305f\u3082\u306e\u3092\u4f5c\u3063\u3066\u307f\u307e\u3057\u305f\u3002","breadcrumb":{"@id":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/#breadcrumb"},"inLanguage":"ja","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/dev.activebasic.com\/egtra\/2014\/02\/17\/645\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u30db\u30fc\u30e0","item":"https:\/\/dev.activebasic.com\/egtra\/"},{"@type":"ListItem","position":2,"name":"COM\u3067\u5f31\u53c2\u7167\u3092\u5b9f\u73fe\u3059\u308b\uff08\u30de\u30eb\u30c1\u30b9\u30ec\u30c3\u30c9\u5bfe\u5fdc\uff09"}]},{"@type":"WebSite","@id":"https:\/\/dev.activebasic.com\/egtra\/#website","url":"https:\/\/dev.activebasic.com\/egtra\/","name":"\u30a4\u30b0\u30c8\u30e9\u30f3\u30b9\u306e\u982d\u306e\u4e2d","description":"\u982d\u306e\u4e2d\u306e\u304b\u3051\u3089\u3002ActiveBasic\u3092\u4e2d\u5fc3\u306b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u306e\u8a71\u3092\u307c\u3061\u307c\u3061\u3068\u3002","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dev.activebasic.com\/egtra\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"ja"},{"@type":"Person","@id":"https:\/\/dev.activebasic.com\/egtra\/#\/schema\/person\/8de756b2ff20b964f64594dfe8f18164","name":"egtra","sameAs":["https:\/\/x.com\/egtra"],"url":"https:\/\/dev.activebasic.com\/egtra\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/posts\/645"}],"collection":[{"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/comments?post=645"}],"version-history":[{"count":0,"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/posts\/645\/revisions"}],"wp:attachment":[{"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/media?parent=645"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/categories?post=645"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.activebasic.com\/egtra\/wp-json\/wp\/v2\/tags?post=645"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}