3 out of 5 rated this helpful - Rate this topic

Rules for Implementing QueryInterface

There are three main rules that govern implementing the IUnknown::QueryInterface method on a COM object:

  • Objects must have identity.
  • The set of interfaces on an object instance must be static.
  • It must be possible to query successfully for any interface on an object from any other interface.

Objects Must Have Identity

For any given object instance, a call to QueryInterface with IID_IUnknown must always return the same physical pointer value. This allows you to call QueryInterface on any two interfaces and compare the results to determine whether they point to the same instance of an object.

The Set of Interfaces on an Object Instance Must Be Static

The set of interfaces accessible on an object through QueryInterface must be static, not dynamic. Specifically, if QueryInterface returns S_OK for a given IID once, it must never return E_NOINTERFACE on subsequent calls on the same object; and if QueryInterface returns E_NOINTERFACE for a given IID, subsequent calls for the same IID on the same object must never return S_OK.

It Must Be Possible to Query Successfully for Any Interface on an Object from Any Other Interface

That is, given the following code:

IA * pA = (some function returning an IA *); 
IB * pB = NULL; 
HRESULT   hr; 
hr = pA->QueryInterface(IID_IB, &pB); 
 

the following rules apply:

  • If you have a pointer to an interface on an object, a call like the following to QueryInterface for that same interface must succeed:
    pA->QueryInterface(IID_IA, ...) 
     
    
  • If a call to QueryInterface for a second interface pointer succeeds, a call to QueryInterface from that pointer for the first interface must also succeed. If pB was successfully obtained, the following must also succeed:
    pB->QueryInterface(IID_IA, ...) 
     
    
  • Any interface must be able to query for any other interface on an object. If pB was successfully obtained and you successfully query for a third interface (IC) using that pointer, you must also be able to query successfully for IC using the first pointer, pA. In this case, the following sequence must succeed:
    IC * pC = NULL; 
    hr = pB->QueryInterface(IID_IC, &pC); 
    pA->QueryInterface(IID_IC, ...) 
     
    

Interface implementations must maintain a counter of outstanding pointer references to all the interfaces on a given object. You should use an unsigned integer for the counter.

If a client needs to know that resources have been freed, it must use a method in some interface on the object with higher-level semantics before calling IUnknown::Release.

Related topics

Using and Implementing IUnknown

 

 

Send comments about this topic to Microsoft

Build date: 3/7/2012

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Identity of objects
Identity of objects is based only on the physical pointer value of IUnknown. If you ask an object for the same interface (not IUnknown), you can receive different values.


Counter of references in 64-bit system
For the counter you should use at least 32-bit unsigned integer. For example, in 64-bit system you can use unsigned long long (unsigned __int64) for it.