c++windowswinapicomout-of-process

How to Get a Registration-Free COM Object Proxy in a Out-of-Process Client


I don't know if there is an API that makes this possible or if I would have to roll my own. Here is what I'm trying to accomplish.

I have an application that connects to an NT service to start a session with another COM server.

The session server will have a running instance for every application instance that connects to the NT service. The application can request that the session server load COM library DLLs and host objects and services from those DLLs in the session server. The DLLs register via registration-free activation.

Creating objects from the session server and passing them back to the application works fine as long as they are IDispatch derived, which is a requirement of entire system since it is expected that scripting languages may use this, and that is the interface requested. C++ application may also use objects hosted in the session server. But IDispatch is an overly verbose interface to deal with in C++.

My question is this:

Given that the DLLs being hosted have dual custom interfaces that the application does know about, and type information about those interface can be read by the application via ITypeInfo; Is there an API that at runtime will create a proxy to mimic the original custom interface if I can provide it the IDispatch interface, which also carries the ITypeInfo information. All the proxy needs is call the IDispatch interface, but appear to C++ as the custom interface. A more optimal solution would be to use the same proxy, the default OLE Automation proxy, that the DLLs registered in its manifest.

I cannot register the proxy/stubs for the DLLs since multiple application may have the same modules, but differing in version, hence the use of registration-free activation.


Solution

  • One option is to give up on the hard-typed dual interface and use IDispatch-only dispinterfaces via hard-typed, compile-time generated smart pointer wrappers. You'd use VC++ #import with raw_dispinterfaces and/or no_dual_interfaces options to generate those.

    The COM marshaler doesn't need a type library to marshal IDispatch::Invoke calls. You'd however need to compile against the version of the type library/DLL you're going to run side-by-side. Or at least make sure the DISPIDs and method signatures remain the same across all versions of the COM DLL. AFAIR, the generated smart pointers don't use IDispatch::GetIdsOfNames, so DISPIDs are hard-coded.

    The IDispatch::Invoke performance might be sub-optional compared to direct dual interface calls, but I don't think it matters, giving the inter-process call scenario you've described. A marshaled out-of-proc COM call is much more expensive than a in-process IDispatch::Invoke call.