I have the following setup. There's a COM server that is installed into COM+ (to run in a separate process) and has this interface definition:
[object, uuid("InterfaceIdHere"), nonextensible, oleautomation, hidden]
interface IMyInterface : IUnknown {
HRESULT MyMethod( [in] IUnknown* param );
};
The caller calls it like this:
HRESULT callComObject(IStream* stream)
{
return comObject->MyMethod(stream);
}
Note that here IStream*
is implicitly upcasted to IUnknown*
. This is done because declaring a parameter of type IStream*
in IDL caused some problems that I can't recall right now. Anyway it's always a valid IStream*
that is passed in place of IUnknown*
.
The COM server side has this implementation of MyMethod()
:
STDMETHODIMP CServer::MyMethod(IUnknown* param)
{
if(param == 0) {
return E_INVALIDARG;
}
ATL::CComQIPtr<IStream> stream(param);
if(stream == 0) {
return E_INVALIDARG;// control passes HERE
}
// whatever
}
So I have IStream*
passed into callComObject()
on the client side which is implicitly upcasted to IUnknown*
and the latter is passed to the COM marshaller. The marshalled IUnknown*
reaches the server in another process and there IUnknown*
is obtained and then there's a QueryInterface()
call to marshall IStream*
from the same object and that QueryInterface()
fails.
This looks insane, because marshalling IStream*
should just work at all times - there's a marshaller for this interface pre-installed in Windows.
Why could it possible not work and how do I find the reason?