OOPortal OOPortal


Basic COM  «Prev  Next»
Lesson 10IUnknown and interface navigation
Objective This page explains interface navigation via IUnknown's QueryInterface method.

IUnknown and Interface Navigation

Previously, we learned that every COM interface implements IUnknown. In this lesson, we will study interface navigation with QueryInterface. The COM specification states that if a client has an interface pointer into a COM object, it must be able to acquire any other interface implemented within that object. In COM terminology, this is called interface navigation.
IUnknown's QueryInterface method supports interface navigation. The following are equivalent prototypes for QueryInterface:

virtual HRESULT __stdcall QueryInterface
  (const IID& riid, void **ppv);
  
virtual HRESULT __stdcall QueryInterface
  (REFIID riid, VOID **ppv);

The second form is the one most often used. REFIID is a macro defined to be const IID & and VOID is a "windows" type defined to be void.
Because every COM interface implements QueryInterface, every COM interface supports interface navigation. The general idea behind implementing QueryInterface is to check the value of the riid parameter against the IIDs of all other interfaces supported by the COM object. If a match is found, the ppv parameter is assigned the value of the requested interface.
As an example, let us use MyComObject from the previous

Essential COM
class CMyComObject :
  public IMyComInterface,
  public IYourComInterface{
   HRESULT __stdcall QueryInterface
     (const IID& iid, void **ppv);
  
   ULONG __stdcall AddRef();
   ULONG __stdcall Release();

   //Methods for IMyComInterface
  
   HRESULT __stdcall Fx1(char *buf);
   HRESULT __stdcall Fx2();

   //Methods for IYourComInterface
   HRESULT __stdcall Zx1(int ix);
};

Following is the implementation of QueryInterface. Hold your cursor over each line for an explanation. The line numbers are added for reference.
  1. Checks to see if the caller (usually the client) is asking for a pointer to IMyComInterface or IUnknown. All COM interfaces must support navigation to IUnknown as well as all other interfaces within the object. If a match is found, the ppv output parameter is assigned to the this pointer using a cast to (IMyComInterface *).
  2. Checks to see if the caller wants an interface pointer to IYourComInterface. If a match is found, the ppv output parameter is assigned to the this pointer with a cast to (IYourComInterface *)
  3. Calls AddRef through the previously assigned ppv output parameter. This is a requirement! In COM, every time we provide an interface pointer to a caller, we must increment its reference count. Lesson 12 discusses AddRef, Release, and reference counting in more detail.
  4. Returns error code E_NOINTERFACE to tell the caller that the COM object does not implement the requested interface.
  5. Returns S_OK to indicate a successful call.