(FreeThreadedMarshaler)

(FreeThreaded Marshaler)

ThreadingModel="Both", , , : STA . , , . , , . , ( , , STA). , , . , ORPC- , , .

, , . , ORPC- , . , ORPC, . . . - CoMarshalInterface / CoUnmarshalInterface. , . , , , . , , , MSHCTX_INPROC.

, IMarshal, , . (FreeThreaded Marshaler - FTM) API- CoCreateFreeThreadedMarshaler:

 HRESULT CoCreateFreeThreadedMarshaler(            [in] IUnknown *pUnkOuter,            [out] IUnknown **ppUnkInner); 

, FTM, , QueryInterface IMarshal. FTM .

 class Point : public IPoint {      LONG m_cRef;      IUnknown *m_pUnkFTM;     long m_x;     long m_y;     Point(void) : m_cRef(0), m_x(0), m_y(0) {          HRESULT hr = CoCreateFreeThreadedMarshaler(this,&m_pUnkFTM);          assert(SUCCEEDED(hr)) ;      }     virtual ~Point(void) { m_pUnkFTM->Release(); }  }; 

QueryInterface IMarshal FTM:

 STDMETHODIMP Point::QueryInterface(REFIID riid, void **ppv)  {      if (riid == IID_IUnknown || riid == IID_IPoint)          *ppv = static_cast<IPoint*>(this);      else if (riid == IID_IMarshal)         return m_pUnkFTM->QueryInterface(riid, ppv);      else          return (*ppv = 0), E_NOINTERFACE;     ((IUnknown* )*ppv)->AddRef();     return S_OK;  } 

FTM, , Point. CoMarshalInterface / CoUnmarshalInterface, , Point , Point.

FTM 16 . , FTM . , . FTM (lazy-aggregated) QueryInterface IMarshal. , :

 class LazyPoint : public IPoint {      LONG m_cRef;      IUnknown *m_pUnkFTM;      long m_x; long m_y;     LazyPoint (void) : m_cRef (0) .m_pUnkFTM(0),m_x(0), m_y(0) {}      virtual ~LazyPoint(void)        { if (m_pUnkFTM) m_pUnkFTM->Release(); }      void Lock(void);        // acquire object-specific lock       //    ,            void Unlock(void);        // release object-specific lock        //    ,          :    :    : }; 

, QueryInterface FTM :

 STDMETHODIMP Point::QueryInterface(REFIID riid, void **ppv)  {      if (riid == IID_IUnknown || riid == IID_IPoint)         *ppv = static_cast<IPoint*>(this);     else if (riid == IID_IMarshal) {         this->Lock();         HRESULT hr = E_NOINTERFACE;          *ppv = 0;          if (m_pUnkFTM == 0)              // acquire FTM first time through              //     FTM           CoCreateFreeThreadedMarshaler(this, &m_pUnkFTM);         if (m_pUnkFTM != 0)              // by here, FTM is acquired              //     FTM             hr = m_pUnkFTM->QueryInterface(riid, ppv);         this->Unlock();          return hr;     } else         return (*ppv = 0), E_NOINTERFACE;     ((IUnknown *)*ppv)->AddRef();     return S_OK;  } 

, QueryInterface IMarshal ( ); , IMarshal , .

, FTM, , FTM . , , , FTM, , . , , FTM. , - :

 class Rect : public IRect  {      LONG m_cRef;      IPoint *m_pPtTopLeft;     IPoint *m_pPtBottomRight;     Rect(void) : m_cRef(0) {          HRESULT hr = CoCreateInstance(CLSID_Point, 0,                                        CLSCTX_INPROC, IID_Ipoint, (void**) &m_pPtTopLeft);         assert(SUCCEEDED (hr));         hr = CoCreateInstance(CLSID_Point, 0, CLSCTX_INPROC,                                IID_Ipoint, (void**)&m_pPtBottomRight);         assert (SUCCEEDED(hr));     }      ;    ;    ; } 

Rect ThreadingModel = "Both". Rect- , CoCreateInstance (CLSID_Rect). , CoCreateInstance (CLSID_Point) . , m_pPtTopLeft m_pPtBottomRight , CoCreateInstance.

, Rect :

 STDMETHODIMP Rect::get_Area(long *pn)  {      long top, left, bottom, right;      HRESULT hr = m_pPtTopLeft->GetCoords(&left, &top);      assert(SUCCEEDED(hr));      hr = m_pPtBottomRight->GetCoords(&right, &bottom);     assert (SUCCEEDED (hr));      *pn = (right - left) * (bottom - top);     return S_OK; } 

Rect FTM, , , CoCreateInstance. , get_Area , . Point FTM, . , ( , Rect), . , Point FTM - ThreadingModel, Rect . , RPC_E_WRONG_THREAD , .

Rect . FTM , Rect , Rect ORPC. , , . - , . (Global Interface Table - GIT). Rect , " " (cookies) DWORD:

 class SafeRect : public IRect {      LONG m_cRef;        //   reference count        //            IUnknown *m_pUnkFTM;       // cache for FTM lazy aggregate        //         FTM      DWORD m_dwTopLeft;       // GIT cookie for top/left        //   GIT    /       DWORD m_dwBottomR1ght;        // GIT cookie for bottom/right        //   GIT    / 

- Point, GIT:

 SafeRect::SafeRect(void) : m_cRef(0), m_pUnkFTM(0)  {        // assume ptr to GIT is initialized elsewhere        //  ,       GIT          //  -             extern IGIobalInterfaceTable *g_pGIT;     assert(g_pGIT != 0);     IPoint *pPoint = 0;        // create instance of class Point        //       Point      HRESULT hr = CoCreateInstance(CLSID_Point, 0,                                    CLSCTX_INPROC, IID_Ipoint, (void**)&pPoint);     assert (SUCCEEDED (hr));        // register interface pointer in GIT        //         GIT      hr =  g_pGIT->RegisterInterfaceInGlobal(pPoint, IID_Ipoint,                                                &m_dwTopLeft);     assert(SUCCEEDED(hr));      pPoint->Release();       // reference is now held in GIT        //         GIT        // create instance of class Point        //       Point      hr = CoCreateInstance(CLSID_Point, 0, CLSCTX_INPROC,                            IID_Ipoint, (void**)&pPoint);     assert(SUCCEEDED(hr));       // register interface pointer in GIT        //         GIT      hr = g_pGIT->RegisterInterfaceInGlobal(pPoint, IID_Ipoint, &m_dwBottomRight);      assert(SUCCEEDED(hr));     pPoint->Release();       // reference is now held in GIT        //         GIT  }  

, , GIT, .

GIT , , :

 STDMETHODIMP SafeRect::get_Area(long *pn)  {     extern IGlobalInterfaceTable *g_pGIT;      assert(g_pGIT != 0);       // unmarshal the two interface pointers from the GIT        //           GIT      IPoint *ptl = 0, *pbr = 0;      HRESULT hr = g_pGIT->GetInterfaceFromGlobal(m_dwPtTopLeft,                             IID_Ipoint, (void**)&ptl);      assert (SUCCEEDED(hr));     hr = g_pGIT->GetInterfaceFromGlobal(m_dwPtBottomRight,                              IID_Ipoint, (void**)&pbr);       // use temp ptrs to implement method        //                  long top, left, bottom, right;      hr = ptl->GetCoords(&left, &top);      assert (SUCCEEDED(hr));      hr = pbr->GetCoords(&right, &bottom);     assert (SUCCEEDED (hr));     *pn = (right - left) * (bottom - top);       // release temp ptrs.        //            ptl->Release();      pbr->Release();     return S_OK; } 

SafeRect FTM, , , .

GIT , GIT. , SafeRect GIT :

 SafeRect::~SafeRect(void)  {     extern IGlobalInterfaceTable *g_pGIT;      assert(g_pGIT != 0);     HRESULT hr = g_pGIT->RevokeInterfaceFromGlobal(m_dwTopLeft);     assert(SUCCEEDED(hr));      hr = g_pGIT->RevokeInterfaceFromGlobal(m_dwBottomRight);     assert(SUCCEEDED(hr)); } 

GIT .

, GIT FTM GIT, , . GIT , . C++ " " GIT , :

 template <class Itf, const IID* piid>  class GlobalInterfacePointer {      DWORD m_dwCookie;        // the GIT cookie        // " " GIT        // prevent misuse        //            GlobalInterfacePointer(const GlobalInterfacePointer&);     void operator =(const GlobalInterfacePointer&);   public:        // start as invalid cookie        //       " "     GlobalInterfacePointer(void) : m_dwCookie(0) { }        // start with auto-globalized local pointer        //                  GlobalInterfacePointer(Itf *pItf, HRESULT& hr)           : m_dwCookie(0) { hr = Globalize(pItf); }        // auto-unglobalize        //            ~GlobalInterfacePointer(void)        { if(m_dw ki ) Unglobalize() ; }        // register an interface pointer in GIT        //         GIT      HRESULT Globalize(Itf *pItf) {          assert (g_pGIT != 0 && m_dwCookie == 0);          return g_pGIT->RegisterInterfaceInGlobal(pItf, * piid, &m_dwCookie);      }        // revoke an interface pointer in GIT        //         GIT      HRESULT Unglobalize(void) {          assert(g_pGIT != 0 && m_dwCookie != 0);         HRESULT hr = g_pGIT->RevokeInterfaceFromGlobal(m_dwCookie);         m_dwCookie = 0;         return hr;     }        // get   local interface pointer from GIT        //           GIT      HRESULT Localize(Itf **ppItf) const {          assert(g_pGIT != 0 && m_dwCookie != 0);         return g_pGIT->GetInte faceFromGlobal(m_dwCookie, *piid, (void**)ppItf);      }        // convenience methods        //            bool IsOK(void) const { return m_dwCookie != 0; }      DWORD GetCookie(void) const { return m_dwCookie; }  };      #define GIP(Itf) GlobalInterfacePointer<Itf, &IID_##Itf>  

, SafeRect DWORD GlobalInterfacePointers:

 class SafeRect : public IRect {      LONG m_cRef:        //  M reference count        //            IUnknown *m_pUnkFTM;       // cache for FTM lazy aggregate        //         FTM      GIP(IPoint) m_gipTopLeft;       // GIT cookie - top/left        // " " GIT    /         GIP(IPoint) m_gipBottomRight;       // GIT cookie - bottom/right        // " " GIT    /         :    :    : }  

GlobalInterfacePointer ( ) , Globalize GlobalInterfacePointer:

 SafeRect::SafeRect(void) : m_cRef (0), m_pUnkFTM(0)  {     IPoint *pPoint = 0;        // create instance of class Point        //       Point      HRESULT hr = CoCreateInstance(CLSID_Point, 0,                    CLSCTX_INPROC, IID_Ipoint, (void**)&pPoint);     assert (SUCCEEDED(hr));       // register interface pointer in GIT        //         GIT      hr = m_gipTopLeft.Globalize(pPoint);     assert (SUCCEEDED(hr));      pPoint->Release();       // reference is now held in GIT        //         GIT        // create instance of class Point        //       Point      hr = CoCreateInstance(CLSID_Point, 0, CLSCTX_INPROC,                            IID_I int, (void**) & int);     assert(SUCCEEDED(hr));       // register interface pointer in GIT        //         GIT      hr = m_gipBottomRight.Globalize(pPoint);      assert (SUCCEEDED (hr));      pPoint->Release();       // reference is now held in GIT        //         GIT  }  

, , Localize GlobalInterfa ePointer:

 STDMETHODIMP SafeRect::get_Top(long *pVal)  {      IPoint *pPoint = 0;       // local imported pointer        //            HRESULT hr = m_gipTopLeft.Localize(&pPoint);     if (SUCCEEDED(hr)){          long x;          hr = pPoint->get_Coords(&x, pVal);         pPoint->Release();      }      return hr;  }  

, (FreeThreaded Marshaler) , , .

. GlobalInterfacePointer , , (smart pointer):

 template <class Itf, const IID* piid>  class LocalInterfacePointer {      Itf *m_pItf;        // temp imported pointer        //              // prevent misuse        //            LocalInterfacePointer(const LocalInterfacePointer&);     operator = (const LocalInterfacePointer&);   public:      LocalInterfacePointer(const GlobalInterfacePointer<Itf, piid>& rhs, HRESULT& hr)      { hr = rhs.Loca1ize(&m_pItf) ; }      LocalInterfacePointer(DWORD dwCookie, HRESULT& hr) {          assert(g_pGIT != 0);         hr = g_pGIT->GetInterfaceFromGlobal(dwCookie, *piid, (void**)&m_pItf);      }      ~LocalInterfacePointer(void) { if (m_pItf) m_pItf->Release(); }    class SafeItf : public Itf {      STDMETHOD_(ULONG, AddRef) (void) = 0;      // hide      //        STDMETHOD_(ULONG, Release)(void) = 0;      // hide      //      };    SafeItf *GetInterface(void) const    { return (SafeItf*) m_pItf; }    SafeItf *operator ->(void) const    { assert(m_pItf != 0); return GetInterface(); }  };  #def1ne LIP(Itf) LocalInterfacePointer<Itf, &IID_##Itf>  

C++ :

 STDMETHODIMP SafeRect::get_Area(long *pn) {      long top, left, bottom, right;      HRESULT hr, hr2;       // import pointers        //          LIP(IPoint) lipTopLeft(m_gipTopLeft, hr);      LIP(IPoint) lipBottomRight(m_gipBottomRight, hr2);     assert(SUCCEEDED(hr) && SUCCEEDED(hr2));       // use temp tocal pointers        //              hr = lipTopLeft->GetCoords(&left, &top);     hr2 = lipBottomRight->GetCoords(&right, &bottom);     assert(SUCCEEDED(hr) && SUCCEEDED(hr2));     *pn = (right - left) * (bottom - top);      return S_OK;       // LocalInterfacePointer auto-releases temp ptrs.        // LocalInterfacePointer            //      }  

GIP LIP GIT FTM . GIT FTM , , .



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