• ### Announcements

#### Archived

This topic is now archived and is closed to further replies.

# QueryInterface

## Recommended Posts

Okay. I'm haveing a separate class for implementing each of my components like this... I1 -> CImpI1 I2 -> CImpI2 I3 -> CImpI3 . . . In -> CImpIn ... and I want the QueryInterface function for each interface to support all the other interfaces, like a good little component should. Well, I'm not sure if the standard way I do QueryInterface would work right for this:
  HRESULT CImp_IX :: QueryInterface ( const IID& iid, void** ppv ) { if ( iid == IID_IUnknown ) { *ppv = static_cast < IX* > ( this ) ; } else if ( iid == IID_IX ) { *ppv = static_cast < IX* > ( this ) ; } else if ( iid == IID_IY ) { *ppv = static_cast < IY* > ( this ) ; } else if ( iid == IID_IZ ) { *ppv = static_cast < IZ* > ( this ) ; } else { *ppv = NULL ; return ( E_NOINTERFACE ) ; } reinterpret_cast < IUnknown* > ( *ppv ) -> AddRef ( VOID ) ; return ( S_OK ) ; } 
I'm not sure if this would cause errors since the interfaces are in separate classes, or if the classes have anything to do with it whatsoever. Thanks in advance. Edited by - Exellon2000 on January 2, 2002 5:49:26 PM Edited by - Exellon2000 on January 2, 2002 5:50:14 PM Edited by - Exellon2000 on January 2, 2002 8:08:48 PM

##### Share on other sites
Hum, I think there will be a problem. You need to make what is call (i think) a Co class than managing the Imp classes.
Like this:

 class CImpClassX1 : public IX1{public:   CImpClassX1( COClassX* pBackObj) //   QueryInterface( ... )    { return pBackObj->QueryInterface( ... ); } // same for add & release refprivate:   // the others methods   COClassX* pBackObj;}class COClassX : public IUnknown{public:    COClassX( ): m_ImpIX1( this) // You will have a warning for calling this in the constructor.    // Addref & Release & Queryprivate:    friend class CImpClassX1;    CImpClassX1  m_ImpIX1;    ULONG m_refCount; // for addref & }COClassX::QueryInterface( ... ){    HRESULT hr = E_NOINTERFACE;    *ppv = NULL;    if (IID_IUnknown == riid){		*ppv = (IUnknown*) this;			    }	else if( IID_IX1 == riid ) { 		*ppv = (IX1*) &m_ImpIX1;    }	else if( IID_IX2 == riid ) { 		*ppv =  (IX2*) &m_ImpIX2;		    }    if (NULL != *ppv){      ((LPUNKNOWN)*ppv)->AddRef();	      hr = NOERROR;    }    return (hr);}

This is A way, many you can do
class COClassX : public IX1, IX2
offenly (just not for aggregation and having 2 function w/ the same prototype).

I have some full source but not really easy, now I prefer using ATL, but doing this in way is needed to understand.

Why English rules?? C pas très malin tout ça!

Edited by - JesterLeCodeur on January 2, 2002 7:47:00 PM

##### Share on other sites
Those should all be dynamic_cast

##### Share on other sites
quote:
Original post by Magmai Kai Holmlor
Those should all be dynamic_cast

Is that all I need to do?

##### Share on other sites
Definitely not.

Your QueryInterface() should only return interface pointers for interface IDs that are directly implemented by that class. Your comment "each interface to support all the other interfaces, like a good little component should" only applies when the class implementing the interfaces supports ALL of the interfaces.

You could use multiple inheritance here, so that your impl class inherits from each interface, but be careful, because the compiler can get confused with all the IUnknown''s flying around =).

Another thing is, remember that any code can call QI() on any of those interfaces to get any other interface (provided it knows the IID to query for), so group interfaces logically by functionality, not for your coding convenience.

-Brannon