I have a COM class CMyCOMServer implementing IMyInterface in one application, both with correct GUIDs. CMyCOMServer::QueryInterface wi
The previous comments about E_NOINTERFACE returned because marshalling interface is missing was very helpful,
however,
for us the answer/fix was to force the main application (the one calling CoCreateInstance) to be STA (single threaded apartment), and this was done by setting an advanced linker option, i.e.:
"CLR Thread Attribute" is set to "STA threading attribute"
or on the link command line you do:
"/CLRTHREADATTRIBUTE:STA"
This prevents a mix of MTA and STA, which causes a call across threads.
Hope someone else finds this helpful.
This happens because COM subsystem tries to marshal your custom interface (IMyInterface) and simply has no idea how to do that. That happens either because the server is out-proc or because the server is in-proc and the thread of the consumer application that calls CoCreateInstance() has called CoInitialize()/ CoInitializeEx() incorrectly so that "multithreaded apartment" is requested as mentioned in the article user Thomas refers to in the other answer.
If you only need an in-proc server you could suppress marshalling by ensuring that the thread calling CoCreateInstance() either calls CoInitialize() or CoInitializeEx() with COINIT_APARTMENTTHREADED to enforce "single-threaded apartment".
If you need an out-proc server you can't get around marshalling. In the latter case you could do one of the following:
Could this be the threading model problem that Raymond Chen wrote about?
Edit in reply to the comment:
If your threading model is incompatible with the threading model of the object you're creating, then COM marshalling kicks in. And if the marshalling stuff isn't there, the error that comes out is E_NOINTERFACE, because the marshalling interface is missing.
It's more about threading models than about marshalling, really.
If your COM server is running in a different process, or a different apartment in the same process, COM needs to know how to package and transmit parameters when you make calls to your interface. This process is called "marshaling".
If you define a custom interface, you need to implement marshaling for it using one of the following approaches.
When you are debugging your COM server, although you see that you are returning your custom interface in the call to QueryInterface, it does not make it across the process boundary because COM cannot figure out how to marshal that interface, hence the client sees E_NOINTERFACE.
UPDATE (based on your comment)
If this is an existing COM server app then you probably already have a proxy/stub. You need to register this on both the client and server. Could it be that you were testing this on a new machine(s) and you simply forgot to register this? To register you simply do regsvr32 on the proxy/stub dll.