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?
Asked
Active
Viewed 1,248 times
-1

Luke
- 5,771
- 12
- 55
- 77
-
Why would you want to do this? – acelent Mar 13 '14 at 17:05
-
@acelent If you implement the interface yourself, it's handy to get the private implementation when you're provided the interface. – Eric Brown Mar 14 '14 at 05:56
-
@EricBrown, that cannot be a good thing across apartments. – acelent Mar 14 '14 at 10:59
-
@EricBrown, it seems this might be the closest thing to `friend` in COM, although in COM friends need to be in the same apartment (pun intended). – acelent Mar 14 '14 at 11:13
1 Answers
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
-
1This 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