如何使用运行对象表(ROT)在两个COM对象之间进行通信?

Mar*_*ski 8 com atl moniker visual-c++

我有两个用C++和ATL编写的COM对象.有一个库,我知道他们的IID和CLID.

我找不到在两个简单COM对象之间进行这种简单通信的示例.如何创建IMoniker以及如何将其添加到ROT?然后,如何在不同的进程/线程中的其他COM中检索此对象的指针?

有没有人可以提供一个小例子?

编辑:更多信息:

我正在为IE写一个附加组件.有两个完全无关的COM对象,即IE加载用于不同目的.一个是BHO(Browser Helper Obect),另一个是异步可插拔协议(APP),我发现我可以通过ROT 在这里进行通信.

Nik*_*lay 8

尝试使用CreateItemMoniker而不是CreatePointerMoniker - 它允许您在ROT中指定对象的名称.

你应该能够像这样注册你的对象:

DWORD RegisterInROT(LPCWSTR szObjName, IUnknown* pObj)
{
  DWORD dwCookie = 0;
  CComPtr<IRunningObjectTable> pROT;
  if (GetRunningObjectTable(0, &pROT) == S_OK)
  {
    CComPtr<IMoniker> pMoniker;
    if (CreateItemMoniker(NULL, szObjName, &pMoniker) == S_OK)
        if (pROT->Register(0, pObj, pMoniker, &dwCookie) == S_OK)
           return dwCookie;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您不希望在没有对象的引用时自动终止对象,则可以指定ROTFLAGS_REGISTRATIONKEEPSALIVE而不是0(在MSDN中签入).该函数返回cookie,您可以使用它来显式从ROT中删除您的对象,如下所示:

void RevokeFromROT(DWORD dwCookie)
{
  CComPtr<IRunningObjectTable> pROT;
  if (GetRunningObjectTable(0, &pROT) == S_OK)
       pROT->Revoke(dwCookie);
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样从ROT获取对象(您应该使用与注册对象相同的名称=)

void GetObjectFromROT(LPCWSTR szObjName, IUnknown** pObj)
{
  CComPtr<IRunningObjectTable> pROT;
  if (GetRunningObjectTable(0, &pROT) == S_OK)
  {
    CComPtr<IMoniker> pMoniker;
    if (CreateItemMoniker(NULL, szObjName, &pMoniker) == S_OK)
        pROT->GetObject(pMoniker, pObj);
  }
}
Run Code Online (Sandbox Code Playgroud)