Skip to main content
gamedev.net
🔒 Locked

QueryInterface

Started by Exellon2000 Jan 2, 2002 at 4:48 PM 3 replies 350+ views
Original Post
Exellon2000
Exellon2000
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
[small]:P I'll lick it if you lick it first :P[small]
jesterlecodeur
jesterlecodeur
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 ref

private:
// 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 & Query
private:
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
_______________
Jester, studient programmerThe Jester Home in French
Shannon Barber
Shannon Barber
Those should all be dynamic_cast
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Exellon2000
Exellon2000
quote:
Original post by Magmai Kai Holmlor
Those should all be dynamic_cast


Is that all I need to do?
[small]:P I'll lick it if you lick it first :P[small]
Brannon
Brannon
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
-Brannon

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.