How to communicate between two COM objects using Running Object Table (ROT)?
Asked Answered
P

1

8

I have two COM objects written in C++ and ATL. There are in one library and I know their IIDs and CLIDs.

I can't find an example of doing this simple communication between two simple COM objects. How to create IMoniker and how to add it to ROT? And then, how to retrieve pointer of this object,in other COM in different process/thread?

Does anyone can provide a small example?

EDIT: More info:

I'm writing an add-on for IE. There are two COM object completely unrelated that IE load for different purpose. One is BHO (Browser Helper Obect), other is Asynchronous Pluggable Protocol (APP) I found I can communicate through ROT here.

Plait answered 1/3, 2011 at 15:29 Comment(9)
Why would you want to use ROT in this case?Lamarre
@Lamarre I'm writing add-on for IE. I updated my question.Plait
Well, I see. You have to search for how to implement IMoniker interface.Lamarre
@Lamarre Do I? I hoped I could use CreatePointerMoniker or other function. But when I register this pointer moniker through IRunningObjectTable::Register I get E_NOTIMPL. Maybe I should use other COM-supplied moniker?Plait
I tried the same - it return E_NOTIMPL to me as well. Are you sure it should work for in-proc servers in the first place?Lamarre
@Lamarre No, I hoped I would find an expert here for which the answer is trivial ;-) Well, I'll have to figure it out my own then.Plait
Well, in this thread ureader.com/msg/14781331.aspx they are discussing very similar code and one of ideas (if I get it right) is that this stuff won't work for an in-proc server.Lamarre
Well, I actually tried exactly the same inside an out-proc server and again it returns E_NOTIMPL.Lamarre
What are you doing that you need the ROT for in the first place? The ROT is only useful if object 1 needs to communicate with object 2 in a different process. If object 1 and object 2 are in the same DLL, just use a shared variable (with appropriate serialization).Besides
N
10

Try using CreateItemMoniker instead of CreatePointerMoniker - it allows you to specify a name for your object in ROT.

You should be able to register your object like this:

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;
}

If you don't want your object to be auto-killed when there are no more references to it, you could specify ROTFLAGS_REGISTRATIONKEEPSALIVE instead of 0 (check in in MSDN). The function returns cookie you can use to explicitly remove your object from ROT later like this:

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

You can get the object from ROT like this (you should use the same name you used to register the object of course =)

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);
  }
}
Ningpo answered 19/11, 2013 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.