Hum sure I'm not clear.
I have use some DirectX interfaces for exemple only. I known that interface are virtual pure. The fact is that i have begin my engine in a true COM objective but with no MIDL ( I want void* ). So I have to design my architecture (taken from COM) manualy.
I think It will derivate all from IUnknow and use IClassFactory.
In the second exemple, I will use the dynamic_cast in the QueryInterface fonction (with an AddRef naturally).
My idea for the second exemple is that having inner class (as the COM illustred in the MSDN have) is very borring because lot of memnber reside in the parent object.
And let's compare the 2 idea
the MSDN (work always)
class COUtilityCar : public IUnknown { public: // Main Object Constructor & Destructor. COUtilityCar(IUnknown* pUnkOuter); ~COUtilityCar(void); // A general public method for initializing this newly created // COUtilityCar object. Creates any subordinate arrays, structures, // or objects. Not exposed as a method in an interface. HRESULT Init(void); // IUnknown members. Main object, non-delegating. STDMETHODIMP QueryInterface(REFIID, PPVOID); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); private: // We show nested interface class implementations here. // We implement the basic ICar interface in this COUtilityCar // COM object class. class CImpICar : public ICar { public: // Interface Implementation Constructor & Destructor. CImpICar(COUtilityCar* pBackObj, IUnknown* pUnkOuter); ~CImpICar(void); // IUnknown members. STDMETHODIMP QueryInterface(REFIID, PPVOID); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // ICar members. STDMETHODIMP Shift(short nGear); STDMETHODIMP Clutch(short nEngaged); STDMETHODIMP Speed(short nMph); STDMETHODIMP Steer(short nAngle); private: // Data private to this interface implementation of ICar ULONG m_cRefI; // Interface Ref Count (for debugging) COUtilityCar* m_pBackObj; // Parent Object back pointer IUnknown* m_pUnkOuter; // Outer unknown for Delegation }; // We implement the IUtility interface (ofcourse) in this COUtilityCar // COM object class. This is the interface that we are using as an // augmentation to the existing COCar COM object class. class CImpIUtility : public IUtility { public: // Interface Implementation Constructor & Destructor. CImpIUtility(COUtilityCar* pBackObj, IUnknown* pUnkOuter); ~CImpIUtility(void); // IUnknown members. STDMETHODIMP QueryInterface(REFIID, PPVOID); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // IUtility members. STDMETHODIMP Offroad(short nGear); STDMETHODIMP Winch(short nRpm); private: // Data private to this interface implementation of IUtility ULONG m_cRefI; // Interface Ref Count (for debugging) COUtilityCar* m_pBackObj; // Parent Object back pointer IUnknown* m_pUnkOuter; // Outer unknown for Delegation }; // Make the otherwise private and nested ICar interface implementation // a friend to COM object instantiations of this selfsame COUtilityCar // COM object class. friend CImpICar; friend CImpIUtility; // Private data of COUtilityCar COM objects. // Nested ICar implementation instantiation. CImpICar m_ImpICar; // Nested IUtility implementation instantiation. CImpIUtility m_ImpIUtility; // Main Object reference count. ULONG m_cRefs; // Outer unknown (aggregation & delegation). IUnknown *m_pUnkOuter; };
|
mine (wich require that if can't be 2 different methods with the same name and typing (Maybe overloading can help in some case)
It's simpler and slower
class COUtilityCar : public IUnknown, ICar, IUtility { public: // Main Object Constructor & Destructor. COUtilityCar(IUnknown* pUnkOuter); ~COUtilityCar(void); // A general public method for initializing this newly created // COUtilityCar object. Creates any subordinate arrays, structures, // or objects. Not exposed as a method in an interface. HRESULT Init(void); // IUnknown members. Main object, non-delegating. STDMETHODIMP QueryInterface(REFIID, PPVOID); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // ICar members. STDMETHODIMP Shift(short nGear); STDMETHODIMP Clutch(short nEngaged); STDMETHODIMP Speed(short nMph); STDMETHODIMP Steer(short nAngle); // IUtility members. STDMETHODIMP Offroad(short nGear); STDMETHODIMP Winch(short nRpm); // Main Object reference count. ULONG m_cRefs; // Outer unknown (aggregation & delegation). IUnknown *m_pUnkOuter; };// and implement the QueryInterface like:HRESULT COUtilityCar::QueryInterface(REFIID riid, PPVOID ppv){ if( riid == IID_ICar ) *ppv = dynamic_cast<ICar> (this); else if( riid == IID_IUtility ) *ppv = dynamic_cast<IUtility> (this); else if( riid == IID_IUnknown ) *ppv = dynamic_cast<IUnknown> (this); else return E_NOINTERFACE; this->AddRef(); return NOERROR;}
|
I tried to use the dynamic method but i have an error
conversion from 'class CStuff *' to 'class IStuff2 *' exists, but is inaccessible
but i'm a beginner in dynamic cast.
I found this Query implementation on a IClassFactory implementation so it give me the idea, but I will use multiple inheritence.
//// Class factory IUnknown implementation//HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv){ if ((iid == IID_IUnknown) || (iid == IID_IClassFactory)) { *ppv = static_cast<IClassFactory*>(this) ; } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; return S_OK ;}
|
Hum a bit long maybe, sorry.
I hope i'm more clear.
Why English rules?? C pas très malin tout ça!
Edited by - jesterlecodeur on June 13, 2001 2:40:55 PM
Edited by - jesterlecodeur on June 13, 2001 4:55:52 PM