Сущность технологии COM




QueryInterface и IUnknown - часть 2


Вооружившись знанием правил IUnknown, полезно исследовать реализацию объекта и убедиться в том, что она придерживается всех этих правил. Следующая реализация выставляет каждый из четырех интерфейсов средств транспорта и IUnknown:

class CarBoatPlane : public ICar, public IBoat, public IPlane { 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); // IBoat methods - методы IBoat STDMETHODIMP Sink(void); // IPlahe methods - методы IPlane STDMETHODIMP TakeOff(void); };

Ниже приведена стандартная реализация QueryInterface в CarBoatPlane:

STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) *ppv = static_cast<ICar*>(this); else if (riid == IID_IVehicle) *ppv = static_cast<ICar*>(this); else if (riid == IID_ICar) *ppv = static_cast<ICar*>(this); else if (riid == IID_IBoat) *ppv = static_cast<IBoat*>(this); else if (riid == IID_IPlane) *ppv = static_cast<IPlane*>(this); else return (*ppv = 0), E_NOINTERFACE; ((IUnknown*)*ppv)->AddRef(); return S_OK; }

Для того чтобы быть объектом СОМ, реализация CarBoatPlane QueryInterface должна полностью придерживаться правил IUnknown, приведенных в данной главе.

Класс CarBoatPlane выставляет интерфейсы только типа ICar, IPlane, IBoat, IVehicle и IUnknown. Каждая таблица vtbl CarBoatPlane будет ссылаться на единственную реализацию QueryInterface, показанную выше. К каждому поддерживаемому интерфейсу можно обращаться через эту реализацию QueryInterface, так что невозможно найти два несимметричных интерфейса, то есть не существует двух интерфейсов A и B, для которых неверно следующее:

If QI(A)->B Then QI(QI(A)->B)->A

Если следовать той же логике, то поскольку все пять интерфейсов принадлежат к одной и той же реализации QueryInterface, не существует трех интерфейсов А, В и С, для которых неверно следующее:




Содержание  Назад  Вперед