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.

Mariusz Pawelski
  • 25,983
  • 11
  • 67
  • 80
  • Why would you want to use ROT in this case? – sharptooth Mar 01 '11 at 15:44
  • @sharptooth I'm writing add-on for IE. I updated my question. – Mariusz Pawelski Mar 01 '11 at 16:05
  • Well, I see. You have to search for how to implement IMoniker interface. – sharptooth Mar 02 '11 at 08:17
  • @sharptooth 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? – Mariusz Pawelski Mar 02 '11 at 12:29
  • 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? – sharptooth Mar 02 '11 at 13:24
  • @sharptooth 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. – Mariusz Pawelski Mar 02 '11 at 13:30
  • Well, in this thread http://www.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. – sharptooth Mar 02 '11 at 13:34
  • Well, I actually tried exactly the same inside an out-proc server and again it returns `E_NOTIMPL`. – sharptooth Mar 02 '11 at 14:51
  • 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). – Eric Brown Sep 09 '13 at 19:29

1 Answers1

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);
  }
}
Nikolay
  • 10,752
  • 2
  • 23
  • 51