Beim Stöbern in den Beispielen zum neuen Platform SDK ist mir das Makro IID_PPV_ARGS aufgefallen, welches häufig bei QueryInterface- und CoCreateInstance-Aufrufen benutzt wird. Die Definition des Makros ist in der Headerdatei objbase.h zu finden und schaut wie folgt aus:
// IID_PPV_ARGS(ppType)
// ppType is the variable of type IType that will be filled
//
// RESULTS in: IID_IType, ppvType
// will create a compiler error if wrong level of indirection is used.
//
extern "C++"
{
template<typename T> void** IID_PPV_ARGS_Helper(T** pp)
{
// make sure everyone derives from IUnknown
static_cast<IUnknown*>(*pp);
return reinterpret_cast<void**>(pp);
}
}
#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
Das Makro stellt sicher, dass QueryInterface und CoCreateInstance immer die zum angeforderten Objekt passende Schnittstellen-IID übergeben bekommen.
Anstatt
...
IShellLinkPtr pShellLink = NULL;
if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &pShellLink)))
return FALSE;
...
schreibt man daher besser
...
IShellLinkPtr pShellLink = NULL;
if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShellLink))))
return FALSE;
...
und verhindert so schon mögliche Fehler während des Quellcode-Schreibens.
