When a COM object is created, the creation method returns an interface pointer. You can then use that pointer to access any of the interface's methods. The syntax is identical to that used with a pointer to a C++ method.
In many cases, the interface pointer that you receive from the creation method may be the only one that you need. In fact, it is relatively common for an object to export only one interface other than IUnknown. However, many objects export multiple interfaces, and you may need pointers to several of them. If you need more interfaces than the one returned by the creation method, there is no need to create a new object. Instead, request another interface pointer by using the object's IUnknown::QueryInterface method.
If you create your object with CoCreateInstance, you can request an IUnknown interface pointer and then call IUnknown::QueryInterface to request every interface you need. However, this approach is inconvenient if you need only a single interface, and it doesn't work at all if you use an object creation method that does not allow you to specify which interface pointer should be returned. In practice, you usually don't need to obtain an explicit IUnknown pointer because all COM interfaces extend the IUnknown interface.
Extending an interface is similar to inheriting from a C++ class. The child interface exposes all of the parent interface's methods plus one or more of its own. In fact, you will often see "inherits from" used instead of "extends." What you need to remember is that the inheritance is internal to the object. Your application cannot inherit from or extend an object's interface. However, you can use the child interface to call any of the child's or the parent's methods.
Because all interfaces are children of IUnknown you can use any of the interface pointers you already have for the object to call QueryInterface. When you do so, you must provide the IID of the interface you are requesting and the address of a pointer that will contain the interface pointer when the method returns. For example, the following code fragment calls IDirectSound9::CreateSoundBuffer to create a primary buffer object. This object exposes several interfaces. The CreateSoundBuffer method returns an IDirectSoundBuffer9 interface. The subsequent code then uses the IDirectSoundBuffer9 interface to call QueryInterface to request an IDirectSound3DListener9 interface.
IDirectSoundBuffer9* pDSBPrimary = NULL; IDirectSound3DListener9* pDSListener; ... if(FAILED(hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ))) return hr; if(FAILED(hr = pDSBPrimary->QueryInterface(IID_IDirectSound3DListener9, (LPVOID *)&pDSListener))) return hr;