5

I use WM_COPYDATA to enable communication between my two processes A and B. There is no problem to exchange data with basic data types.

Now I have a problem, in some case I want to pass an Interface (IDispatch) from my process A to my process B. Is it possible?

stanleyxu2005
  • 8,081
  • 14
  • 59
  • 94
  • 1
    No direct experience with WM_COPYDATA. But ave you checked this - http://www.codeproject.com/Articles/5307/Use-WM_COPYDATA-to-send-data-to-from-C-and-C-Windo. Also Joseph Newcomer seems to suggest it is possible - http://www.flounder.com/wm_copydata.htm (and he generally is right with all things Win32) – Gangadhar Apr 08 '12 at 05:09
  • @Gangadhar This is a very nice link. Issue comes from the fact that all data has to be serialized into the WM_COPYDATA buffer - you can do it by hand (as the author suggests), or rely on automated marshaling, like COM or mORMot. – Arnaud Bouchez Apr 08 '12 at 08:19
  • 1
    Maybe I'm totally off, but what about [ObjectFromLresult](http://msdn.microsoft.com/en-us/library/windows/desktop/dd373605%28v=vs.85%29.aspx) and [LresultFromObject](http://msdn.microsoft.com/en-us/library/windows/desktop/dd318557%28v=vs.85%29.aspx)? – kobik Apr 08 '12 at 09:21
  • @kobik The interface is only meaningful in the process that created it, that's the problem – David Heffernan Apr 08 '12 at 11:23
  • @DavidHeffernan, Yeah but I know that the functions above are used to grab an external `IHTMLDocument2` interface (the object must implement `IAccessible`), so I thought It might help... – kobik Apr 08 '12 at 11:48
  • @kobik AFAIK Those functions are internal functions used by Active Accessibility COM interface... nothing to do with the OP question. See http://msdn.microsoft.com/en-us/library/windows/desktop/dd373592(v=vs.85).aspx – Arnaud Bouchez Apr 08 '12 at 17:25

2 Answers2

12

It is not possible to directly pass an interface pointer to another process. Like any other pointer, an interface is only valid in the process address space that instantiates it at runtime. COM has its own mechanism for marshaling interfaces and data across process boundaries, even across different apartments in the same process. In the case of interfaces, that involves proxies and stubs which run in each process/apartment and communicate with each other using various IPC mechanisms, such as pipes, RPC, or TCP/IP. Have a look at these articles for how using interfaces across processes/apartments is accomplished:

Inter-Object Communication

Understanding Custom Marshaling Part 1

To do what you are asking for, without resorting to implementing custom marshaling, you would have to make one of the processes act as an out-of-process COM server, and then the other process can use CoCreateInstance() or GetActiveObject() to obtain an interface pointer to the server's object that works within its local address space, and let COM handle the marshaling details for you.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
8

It can't be done directly, but you can use a Client-Server service framework, which may be interface based.

For instance, see the last feature of our Open Source mORMot framework: Interface based services sample code and this link.

You can execute an interface on a remote process. The feature handles all communication means of the framework, i.e. in-process call, GDI messages, named pipes and TCP/HTTP. Internally it will use WM_COPYDATA for GDI messages, then transmit the parameters and results as JSON. Use this link to download the source code (use the http://synopse.info/fossil 1.16+ version) and the documentation (there are several pages about how to implement those services).

It is an Open-Source project, working with Delphi 6 up to XE2.

You can also expose your interface with a SOAP or DataSnap Client-Server (if you have the corresponding version of Delphi), or n-Tier commercial packages (like http://www.remobjects.com/da). This is similar to the method implemented in mORMot.

COM is also a good candidate, native to Windows, but it is more difficult to initialize: you'll have to register the COM on each PC (with administrator rights), and you won't be able to make it work over a network (DCOM is deprecated, remember). COM is good if you want your service to be shared with other languages, like .Net, but only locally.

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159