Как установить связь между двумя COM-объектами, используя таблицу бегущих объектов (ROT)? - PullRequest
8 голосов
/ 01 марта 2011

У меня есть два COM-объекта, написанных на C ++ и ATL.Они есть в одной библиотеке, и я знаю их IID и CLID.

Я не могу найти пример такой простой связи между двумя простыми объектами COM.Как создать IMoniker и как добавить его в ROT?А потом, как получить указатель этого объекта, в другой COM в другой процесс / поток?

Кто-нибудь может привести небольшой пример?

РЕДАКТИРОВАТЬ : Дополнительная информация:

Я пишу дополнение для IE.Есть два COM-объекта, совершенно не связанных между собой, которые IE загружают для разных целей.Один из них - BHO (Browser Helper Obect), другой - Асинхронный подключаемый протокол (APP). Я обнаружил, что могу общаться через ROT здесь .

1 Ответ

8 голосов
/ 19 ноября 2013

Попробуйте использовать 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;
}

Если вы не хотите, чтобы ваш объект автоматически уничтожался, когда на него больше нет ссылок, вы можете указать ROTFLAGS_REGISTRATIONKEEPSALIVE вместо 0 ( регистрация в MSDN ).Функция возвращает cookie, который вы можете использовать для явного удаления вашего объекта из ROT позже, например так:

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

Вы можете получить объект из 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);
  }
}
...