-1

When I have a instance of an interface like IMediaSample can i cast it to a class that implements this interface like CMediaSample? If yes, how?

Luke
  • 5,771
  • 12
  • 55
  • 77

1 Answers1

1

While you can't cast interface pointers to get to the base class (because the interface you're given isn't necessarily the one you implemented), you can define a custom IID for QueryInterface that your QI implementation would return 'this'. E.g:

STDMETHOD(QueryInterface)(IN REFIID riid, OUT void** ppv)
{
    *ppv = NULL;

    // IUnknown can require extra casting to pick out a specific IUnknown instance
    // otherwise compiler will complain about an ambiguous cast. Any IUnknown will do,
    // we know they're all the same implementation, so even casting to CFooHandler then IUnknown is fine here.
    // Here am assuming that CUnknown implements IUnknown
    if(riid == __uuidof(IUnknown))
        *ppv = static_cast<IUnknown*>(static_cast<CUnknown*>(this));
    else if(riid == __uuidof(IFoo))
        *ppv = static_cast<IFoo*>(this);
    else if(riid == __uuidof(IBar))
        *ppv = static_cast<IBar*>(this);
    else if(riid == __uuidof(IThis))
        *ppv = this;
    else
        return E_NOINTERFACE;
}

This technique has been around for a while; Chris Sells created a macro called COM_INTERFACE_ENTRY_THIS that makes it trivial to implement in an ATL COM interface map.

This doesn't work for tear-off interfaces, obviously, but if you're doing that, then you would know to QI for the base interface and then for the implementation.

Eric Brown
  • 13,774
  • 7
  • 30
  • 71
  • 1
    This answer should come with a warning: this technique implies `QueryInterface`ing for the *special* IID in the same apartment, and the chosen IID should not be marshable so you get an error across apartments. – acelent Mar 14 '14 at 11:11
  • Internet Explorer seems to use this technique: [CLSID_CMarkup](http://msdn.microsoft.com/en-us/library/aa770042.aspx#wbc_clsidmkup). – acelent Mar 14 '14 at 11:20