I’m working on a desktop app that has WPF GUI and unmanaged C++ backend. I’ve defined API the following way (C# version, truncated):
[Guid( \"###\" ), Interface
As hinted by Hans Passant, the key here is CoCreateFreeThreadedMarshaler API.
Add a private variable CComPtr<IUnknown> m_ftm;
Initialize that marshaller:
HRESULT FinalConstruct()
{
IUnknown* pUnk = GetUnknown();
return CoCreateFreeThreadedMarshaler( pUnk, &m_ftm );
}
Process IID_IMarshal in QueryInterface, by adding the following line to the interface map:
COM_INTERFACE_ENTRY_AGGREGATE( IID_IMarshal, m_ftm )
After that, C# code will happily call those objects from any thread. Of course you'll have to handle synchronization yourself, CComAutoCriticalSection / CComCritSecLock often help.
Update: MS broke my code in VS 2017, updated the answer. See edit history for VS2015 version.