Essential COM

, QueryInterf , , , , . , . , , , . " " , " ", . " " , " ", . " " (from that point on) " , ". C++, , ( , , ).

, , , , , , , :

void AssertStaticType(IUnknown *pUnk, REFIID riid) { IUnknown *pUnk1 = 0, *pUnk2 = 0; HRESULT hr1 = pUnk->QueryInterface(riid, (void**)&pUnk1); HRESULT hr2 = pUnk->QueryInterface(riid, (void**)&pUnk2); // both requests for the same interface should // yield the same yes/no answer // // / assert(SUCCEEDED(hr1) == SUCCEEDED(hr2)); if (SUCCEEDED(hr1)) pUnk1->Release(); if (SUCCEEDED(hr2)) pUnk2->Release(); }

, :

  1. , QueryInterface ( , IMorning ( ) 12:00).
  2. , QueryInterface ( , INotBusy ( ), ).
  3. (security token) , QueryInterface. 6, - (wire protocol), .
  4. , QueryInterface ( , IHaveTonsOfMemory ( ) malloc(4096*4096)).

, "barring catastrophic failure" ( ).

, " / " . , ICar, IBoat IPlane, - . , , " " " " . , , :

class : public ICar, public IPlane, public IBoat { enum TYPE { CAR, BOAT, PLANE, NONE }; TYPE m_type; CBP(void) : m_type(NONE) { } STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { if (md == IID_ICar) { // 1st QI Initializes type of object // QI if (m_type == NONE) m_type = CAR; // only satisfy request if this object is a car // , // car ( ) if (m_type == CAR) *ppv = static_cast<ICar*>(this); else return (*ppv = 0), E_NOINTERFACE; } else if (md == IID_IBoat) { // similar treatment for IBoat and IPlane // IBoat IPlane } };

, , , , , " / " . , , , QueryInterface , . " " (client-side proxies) QueryInterface - . , , QueryInterface .

Категории