Is 32bit C++ native application client vs. .NET 6 out-of-proc server with registry-free possible?
See the question and my original answer on StackOverflowCOM does allow 32bit <=> 64 bits cross-process communication between clients and servers. It "just" requires them to properly implement marshaling: proxy / stub for IUnknown-derived interfaces and/or type libraries (.tlb) for IDispatch-derived interfaces.
The difficulty with reg-free COM is it's relatively recent (more than COM itself) and poorly supported by tooling and documentation.
The idea is really for COM servers and COM clients to declare:
- as a COM server, what services (COM objects, COM interfaces) they serve
- as a COM client, what services they need
And both sides also need to declare how connection will work, which is how these interfaces will be marshaled across processes, possibly including satellite files or embedded resources.
To "declare this, both sides use Application manifests, to enable COM to find the same information it would have found looking in the registry, but now without using it.
I've made a full working sample here on github: RegfreeNetComServer. In this sample, the server application manifest looks like this:
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- server name can be anything but must not collide with client -->
<assemblyIdentity version="1.0.0.0" name="RegfreeNetComServer.app"/>
<!-- this means hey, "there's a satellite file I come with" -->
<file name="server.tlb">
<!-- this means "and it contains a typelib with this id" -->
<typelib tlbid="{46F3FEB2-121D-4830-AA22-0CDA9EA90DC3}"
version="1.0" helpdir="" />
</file>
<!-- this is for an IDispatch-derived interface named "IServer" -->
<comInterfaceExternalProxyStub
iid="{F586D6F4-AF37-441E-80A6-3D33D977882D}"
name="IServer"
tlbid="{46F3FEB2-121D-4830-AA22-0CDA9EA90DC3}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" />
... other things
</assembly>
For the client, it's the same, but the identity (the client's app) is obviously different:
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- client name can be anything but must not collide with server -->
<assemblyIdentity version="1.0.0.0" name="NativeClient.app" type="win32" />
<!-- the rest is identical since the tlb file is the same in this case -->
<file name="server.tlb">
<!-- this means "and it contains a typelib with this id" -->
<typelib tlbid="{46F3FEB2-121D-4830-AA22-0CDA9EA90DC3}"
version="1.0" helpdir="" />
</file>
<comInterfaceExternalProxyStub
iid="{F586D6F4-AF37-441E-80A6-3D33D977882D}"
name="IServer"
tlbid="{46F3FEB2-121D-4830-AA22-0CDA9EA90DC3}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}" />
</assembly>
In my sample, the tlb is in an external "server.tlb" file, and this file must simply be present aside both client and server .exe, but it can also be embedded as a Win32 resource in each of these. .NET 6+ allows this, Visual Studio C++ allows this for native projects.
If your reg-free configuration is really invalid, you'll get Windows' MessageBox alerts with errors. The easier to fix is to check the Event Viewer / Application tab which contains quite informative events.