ActiveX ActiveX - 23 days ago 7
C++ Question

In-Proc COM object sharing across another Process

Before I ask this question I would like to make it clear that I know there are libraries and techniques for Inter process communcation. This though, is a learning question about COM.
I also do know about out-of-proc servers but that's not what I am looking for.

The question:

What I want to know, because I don't know this, is it possible, and if yes how, to share an in-proc COM object (object defined in a DLL) living in one process (has been instantiated in the process) across another process? Ie, how do I obtain a pointer to the in-proc object from proces A in process B?

Thanks in advance.

Answer

Yes, it's possible. The underlying principle is the same regardless of whether you are sharing a single object instance between apartments in a single process, or between separate processes.

There's two approaches here: perhaps the simplest is to use the Running Object Table: this is essentially a workstation-wide table of named COM objects. You have one process add an object to the table with a well-known name, and have the other process look up that object.

The other approach is to use marshaling. Marshaling is the process of using a COM API to get a series of bytes that describe the location of an object. You can then copy that series of bytes to another process using any means you want to (shared memory, file, pipe, etc), and then use another COM API in the receiving process to unmarshal the object; COM then creates a suitable remoting proxy in that process that communicates back to the original one. Check out the APIs CoMarshalIntefcace and CoUnmarshalInterface for more details.

Note that both of these require that you have suitable remoting support in place for the object; the interfaces you are using need to be described in IDL and compiled and registered appropriately.

--

I don't have code handy for either of these cases unfortunately.

For the CoMarshalInterface approach, the process is something like:

  • Use CreateStreamOnHGlobal (with NULL hglobal) to create an IStream that's backed by a HGLOBAL that COM allocates as needed
  • Use CoMarshalInterface to marshal the interface pointer to the stream (which in turn writes it to the memory backed by the HGLOBAL)
  • Use GetHGlobalFromStream to get the HGLOBAL from the stream
  • Use GlobalLock/GlobalSize to lock the HGLOBAL and access the marhaled data (GlobalUnlock when done)
  • Use whatever means you want to to copy the bytes to the target process.

On the far side, use:

  • GlobalAlloc/GlobalLock/GlobalUnlock to create a new HGLOBAL and populate it with the marshaled data
  • CreateStreamOnHGlobal with your new HGLOBAL
  • Pass this stream to CoUnmarshalInterface

Normal COM and Windows refcounting/resource rules apply across all of this; AddRef/Release as appropriate; use GlobalFree to free any HGLOBALs that you allocate, etc.

Comments