Essential COM

C++. , vptr vtbl. , vtbl , . , QueryInterface, AddRef Release, , ( ). , . .

. ICar ( ) , GetMaxSpeed ( ). IBoat ( ) IPlane ( ) , GetMaxSpeed . , GetMaxSpeed , vtbl, ICar, IBoat IPlane , .

, . , , ? , . C++, :

 struct IXCar : public ICar {       // add new non-clashing method as pure virtual       //                  virtual HRESULT STDMETHODCALLTYPE GetMaxCarSpeed(long *pval) = 0;       // implement clashing method by upcalling       // non-clashing implementation in derived class       //                //              STDMETHODIMP GetMaxSpeed(long *pval)       { return GetMaxCarSpeed(pval); } }; 

, IBoat IPlane , GetMaxSpeed GetMaxSpeed:

 class CarBoatPlane : public IXCar,                      public IXBoat,                      public IXPlane {    public:       // Unknown methods -   IUnknown      STDMETHODIMP QueryInterface(REFIID, void**);     STDMETHODIMP_(ULONG) AddRef(void);     STDMETHODIMP_(ULONG) Release(void);       // IVehicle methods -   IVehicle        // do not override GetMaxSpeed!        //     GetMaxSpeed!        // ICar methods -   ICar      STDMETHODIMP Brake(void);       // IBoat methods -   IBoat      STDMETHODIMP Sink(void);       // IXPlane methods -   IXPlane      STDMETHODIMP TakeOff(void);       // upcalled from IXCar::GetMaxSpeed        //     IXCar::GetMaxSpeed      STDMETHODIMP GetMaxCarSpeed(long *pval);       // upcalled from IXBoat::GetMaxSpeed        //     IXBoat::GetMaxSpeed      STDMETHODIMP GetMaxBoatSpeed(long *pval);       // called from IXPlane::GetMaxSpeed        //     IXPlane::GetMaxSpeed      STDMETHODIMP GetMaxPlaneSpeed(long *pval); } 

4.6 vtbl. , GetMaxSpeed . CarBoatPlane , CarBoatPlane . , CarBoatPlane GetMaxSpeed, , , IXCar, IXBoat IXPlane. , , ( ) .

 . 4.6.

, IUnknown. , C++. C++, , . , vtbl QueryInterface. C++ C++ . , , QueryInterface, . :

 class CarPlane {      LONG m_cRef;     CarPlane(void) : m_cRef(0) {}    public:       // Main IUnknown methods       //     IUnknown     STDMETHODIMP QueryInterface(REFIID, void**);     STDMETHODIMP_(ULONG) AddRef(void);     STDMETHODIMP_(ULONG) Release(void);   private:       // define nested class that implements ICar       //      ,   ICar     struct XCar : public ICar {           // get back pointer to main object           //                    inline CarPlane* This();         STDMETHODIMP QueryInterface(REFIID, void**);         STDMETHODIMP_(ULONG) AddRef(void);         STDMETHODIMP_(ULONG) Release(void);         STDMETHODIMP GetMaxSpeed(long *pval);         STDMETHODIMP Brake(void);     };       // define nested class that implements IPlane        //      ,   IPlane      struct XPlane : public IPlane {            // Get back pointer to main object            //                      inline CarPlane* This();         STDMETHODIMP QueryInterface(REFIID, void**);         STDMETHODIMP_(ULONG) AddRef(void);         STDMETHODIMP_(ULONG) Release(void);         STDMETHODIMP GetMaxSpeed(long *pval);         STDMETHODIMP TakeOff(void);     };       // declare instances of nested classes       //            XCar m_xCar;     XPlane m_xPlane; }; 

, , CarPlane. 4.7 vtbl.

 . 4.7.  ,

, , . GetMaxSpeed:

 STDMETHODIMP CarPlane::XCar::GetMaxSpeed(long *pn) {       // set *pn to max speed for cars       //   *pn        } STDMETHODIMP CarPlane::XPlane::GetMaxSpeed(long *pn) {       // set *pn to max speed for planes        //   *pn        } 

, GetMaxSpeed , , vtbl, ICar IPlane, GetMaxSpeed.

, CarPlane, , IUnknown, IUnknown . CarPlane , . , , static_cast vptr, QueryInterface CarPlane , :

 STDMETHODIMP CarPlane::QueryInterface(REFIID riid, void **ppv)  {      if (riid == IID_IUnknown)         *ppv = static_cast<IUnknown*>(&m_xCar);     else if (riid == IID_IVehicle)         *ppv = static_cast<IVehicle*> (&m_xCar);     else if (riid == IID_ICar)         *ppv = static_cast<ICar*>(&m_xCar);     else if (riid == IID_IPlane)         *ppv = static_cast<IPlane*>(&m_xPlane);     else         return (*ppv = 0), E_NOINTERFACE;     ((IUnknown*)(*ppv))->AddRef();     return S_OK; } 

CarPlane QueryInterface, QueryInterface CarPlane. , - . CarPlane::XCar , this this .

 inline CarPlane CarPlane::XCar::This(void)  {     return (CarPlane*)((char*)this         // ptr to composite -                  - offsetof (CarPlane, m_xCar)); } inline CarPlane CarPlane::XPlane::This(void)  {      return (CarPlane*)((char*)this          // ptr to composite -                  - offsetof(CarPlane, m_xPlane)); } 

(back-pointer) , . QueryInterface :

 STDMETHODIMP CarPlane::XCar::QueryInterface(REFIID r, void**p) {     return This()->QueryInterface(r, p); }  STDMETHODIMP CarPlane::XPlane::QueryInterface(REFIID r, void**p) {      return This()->QueryInterface(r, p); } 

this AddRef Release ( ) .

, , , . , , , ( , ), . , CarPlane , , . , MFC (Microsoft Foundation Classes Microsoft) . , . , , , , , , . , , GetMaxSpeed, , , , . , . , .

. , vtbl AddRef Release. :

 STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {     if (riid == IID_IBoat) {           // allocate resource the first time through           //                  if (m_pTonsOfMemory == 0)             m_pTonsOfMemory = new char[4096 * 4096];             *ppv = static_cast<IBoat*>(this);         }         else if ... } 

, IBoat, Release, IBoat, Release, . , AddRef Release IBoat . IBoat , AddRef Release, , :

 class CarBoatPlane : public ICar, public IPlane {     LONG m_cRef;     char *m_pTonsOfMemory;     CarBoatPlane (void) : m_cRef(0), m_pTonsOfMemory (0) {}   public:       // IUnknown methods -   IUnknown      STDMETHODIMP QueryInterface(REFIID, void**);     STDMETHODIMP_(ULONG) AddRef(void);     STDMETHODIMP_(ULONG) Release(void);       // IVehicle methods -   IVehicle      STDMETHODIMP GetMaxSpeed(long *pMax);       // ICar methods -   ICar      STDMETHODIMP Brake(void);       // IPlane methods -   IPlane      STDMETHODIMP TakeOff(void);       // define nested class that implements IBoat       //      ,   IBoat     struct XBoat : public IBoat {           // get back pointer to main object           //                    inline CarBoatPlane* This();         LONG m_cBoatRef;           // per-interface ref count            //                    XBoat(void) : m_cBoatRef(0) {}          STDMETHODIMP QueryInterface(REFIID, void**);         STDMETHODIMP_(ULONG) AddRef(void);         STDMETHODIMP_(ULONG) Release(void);         STDMETHODIMP GetMaxSpeed(long *pval);         STDMETHODIMP Sink(void);     };     XBoat m_xBoat; }; 

AddRef Release IBoat IBoat , :

 STDMETHODIMP_(ULONG) CarBoatPlane::XBoat::AddRef()  {     ULONG res = InterlockedIncrement(&m_cBoatRef);     if (res == 1) {           // first AddRef -   AddRef           // allocate resource and forward AddRef to object           //         AddRef            This()->m_pTonsOfMemory = new char[4096*4096];         This()->AddRef();     }     return res; } STDMETHODIMP_(ULONG) CarBoatPlane::XBoat::Release()  {      ULONG res = InterlockedDecrement(&m_cBoatRef);     if (res == 0) {           // last Release -   Release           // free resource and forward Release to object           //         Release            delete [] This()->m_pTonsOfMemory;         This()->Release();     } return res; } 

, : Release , AddRef. QueryInterface :

 ((IUnknown*)(*ppv))->AddRef();   // use exact ptr    //        return S_OK; 

:

 AddRef();   // just call this->AddRef    //     this->AddRef return S_OK; 

,

 IBoat *pBoat = 0; HRESULT hr = pUnk->QueryInterface(IID_IBoat, (void**)&pBoat); if (SUCCEEDED(hr)) {      hr = pBoat->Sink();     pBoat->Release(); } 

AddRef Release .

QueryInterface. , , , , , , IUnknown :

 class CarBoatPlane : public ICar, public IPlane {    public:     struct XBoat : public IBoat {            // composite QI/AddRef/Release/This()            //     QI/AddRef/Release/This()          IMPLEMENT_COMPOSITE_UNKNOWN(CarBoatPlane, XBoat, m_xBoat)          STDMETHODIMP GetMaxSpeed(long *pval);         STDMETHODIMP Sink(void);     };     XBoat m_xBoat;       // IVehicle methods        //   IVehicle      STDMETHODIMP GetMaxSpeed(long *pMax);            // ICar methods        //   ICar      STDMETHODIMP Brake(void);       // IPlane methods        //   IPlane      STDMETHODIMP TakeOff(void);       // standard heap-based QI/AddRef/Release       //       " " QI/AddRef/Release     IMPLEMENT_UNKNOWN(CarBoatPlane)     BEGIN_INTERFACE_TABLE(CarBoatPlane)     IMPLEMENTS_INTERFACE_AS(IVehicle, ICar)      IMPLEMENTS_INTERFACE(ICar)     IMPLEMENTS_INTERFACE(IPlane)       // macro that calculates offset of data member       //  ,            IMPLEMENTS_INTERFACE_WITH_COMPOSITE(IBoat, XBoat, m_xBoat)      END_INTERFACE_TABLE()  }; 

QueryInterf , AddRef Release. , , :

 // inttable.h // (book-specific header file) // (   ,        )  #define COMPOSITE_OFFSET(ClassName, BaseName, \                          MemberType, MemberName) \                          (DWORD(static_cast<BaseName*>(\                           reinterpret_cast<MemberType*>(0x10000000 + \                           offsetof(ClassName, MemberName)))) - 0 10000000) #define IMPLEMENTS_INTERFACE_WITH_COMPOSITE(Req,\                                             MemberType, MemberName) \                      { &IID_##Req,ENTRY_IS_OFFSET, COMPOSITE_OFFSET(_IT,\                        Req, MemberType, MemberName) },  // impunk.h // (book-specific header file) // (   ,        ) #def1ne IMPLEMENT_COMPOSITE_UNKNOWN(OuterClassName,\                                     InnerClassName, DataMemberName) \                                      OuterClassName *This() \                      { return (OuterClassName*)((char*)this - \                          offsetof(OuterClassName, DataMemberName)); }\                      STDMETHODIMP QueryInterface(REFIID riid, void **ppv)\                      { return This()->QueryInterface(riid, ppv); }\                     STDMETHODIMP_(ULONG) AddRef(void) \                      { return This()->AddRef(); }\                      STDMETHODIMP_(ULONG) Release(void) \                      { return This()->Release(); } 

QueryInterface, AddRef Release, .



Suschnost' tehnologii SOM
Essential COM
ISBN: 0201634465
EAN: 2147483647
Year: N/A
Pages: 103
Authors: Don Box

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net