In this C++/COM shell extension tutorial, the programmer demonstrates (for purposes of edification) that you can forego calling QueryInterface() and simply pass around a general object instead. At least that works when implementing DllGetClassObject(). He says the purpose of QueryInterface() is just to have each object speak for itself as to whether it supports a given interface.
Microsoft, meanwhile, seems to say that QueryInterface() is necessary to get a pointer to a specific interface on an object.
So to what extent is QueryInterface() necessary? Is there any time when calling QueryInterface() is absolutely essential, and without it the code wouldn't work? Or is getting the object itself technically sufficient, as the video tutorial suggests?
No, as a general rule you cannot skip calling
QueryInterfaceunless you know the interface pointer you have is already correct.If we imagine a object that implements IFoo and IBar the layout might look something like this:
A instance of the object might point to
IFoos v-table pointer orIBars v-table pointer. Calling the 4th method without knowing which one it really is will crash because the parameter count is not the same. And even if the signature was the same, calling arbitrary methods is not a good idea.The video you are referring to gets away with it only because callers of
DllGetClassObjectusually only ask forIClassFactory. But even there it is not safe because somebody might ask forIClassFactory2instead. CorrectDllGetClassObjectimplementations should therefore also callQueryInterface.I would recommend trying to code in C instead of C++ when learning COM fundamentals, this forces you to handle all v-table indirection yourself. Take a look at this series for details.