Take the 2-minute tour ×

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?

share|improve this question
Call QueryInterface() directly instead of using CComQIPtr and then you can check what HRESULT value it is actually returning. –  Remy Lebeau May 16 '13 at 14:34
@RemyLebeau: The HRESULT is E_NOINTERFACE. –  sharptooth May 16 '13 at 14:40
Are you using the implicit OLEAUT marshaler? or a custom proxy/stub? Is the standard OLEAUT marshaler supposed to marshal anything else that Variant Types if it's not aware (ie: if the idl/typelib doesn't say anything about it) –  Simon Mourier May 16 '13 at 15:05
@SimonMourier: I rely on OleAut marshaller, there's no custom proxy/stub. –  sharptooth May 16 '13 at 15:52
"IStream* is implicitly upcasted to IUnknown*". If you had done that via COM, i.e. via IStream::QueryInterface(IID_IUnknown), you'd have AddRef'ed the new interface. Are you by any chance releasing the stream too early? –  MSalters May 16 '13 at 22:32

3 Answers 3

up vote 3 down vote accepted

One of the possible scenarios that matches the behavior is the following:

  • you don't have any marhshaling between caller and callee
  • the interface pointer is valid
  • however the object which implements IStream, does not have a corresponding COM_INTERFACE_ENTRY map entry and does not make the interface available, the caller might have obtained the pointer via non-COM way, e.g. direct C++ cast

This is easy to check by QueryInterface'ing the stream on the caller side before the call.

The callee in this scenario can just reinterpret_cast to IStream and have it nicely working.

share|improve this answer
It's indeed a good idea to check if you can QI the IStream* in the absence of marshalling. –  MSalters May 16 '13 at 22:26

You can either have your IDL import objidl.idl, or define IStream (and ancestors) manually in your own IDL (just be sure to use the standard IID value for it). Then you can use IStream instead of IUnknown as your parameter type and not worry about QueryInterface() anymore.

share|improve this answer

you may replace IUnknown by IDispatch as parameter type of your method. In my mind, the server actually has a stub instead of the stream itself since it is in another process.

this is just a guess

I hope this helps

share|improve this answer
Yes, it only has a stub, but QueryInterface() should be forwarded to the client side and retrieve the right interface and get it back. –  sharptooth May 16 '13 at 14:41
@sharptooth apologies, you're perfectly right –  loic May 16 '13 at 19:20

Your Answer


