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




Двоичная композиция - часть 7


STDMETHODIMP_(ULONG) Car::Release (void) { return m_pUnkOuter->Release(); }

Рис. 4.8. Агрегируемый Car

Эти подпрограммы являются версиями, которые будут заполнять таблицы vtbl всех интерфейсов объекта, так что какой бы интерфейс клиент ни получил, методы IUnknown всегда передают функции основной идентификационной единице объекта.

Для того чтобы объект можно было использовать в обоих сценариях — агрегирования и автономном — разработчик объекта должен установить свой элемент данных m_pUnkOuter так, чтобы в случае автономного режима он указывал на собственный неделегирующий IUnknown:

Car::Car(IUnknown *pUnkOuter) { if (pUnkOuter) // delegate to pUnkOuter // делегируем в pUnkOuter m_pUnkOuter = pUnkOuter; else // delegate to non-delegating self // делегируем неделегирующему себе m_pUnkOuter = &m_innerUnknown; }

Разработчик обеспечивает то, что в обоих случаях m_pUnkOuter указывает на нужную для данного объекта реализацию QueryInterface, AddRef и Release.

Обычные неделегирующие реализации QueryInterface, AddRef и Release являются вполне правильными и предсказуемыми:

STDMETHODIMP Car::InternalQueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(&m_innerUnknown); else if (riid = IID_IVehicle) *ppv = static_cast<IVehicle*>(this); else if (riid == IID_ICar) *ppv = static_cast<ICar*>(this); else return (*ppv = 0), E_NOINTERFACE; ((IUnknown*)*ppv)->AddRef(); return S_OK; }

STDMETHODIMP_(ULONG) Car::InternalAddRef(void) { return InterlockedIncrement(&m_cRef); }

STDMETHODIMP_(ULONG) Car::InternalRelease(void) { ULONG res = InterlockedDecrement(&m_cRef); if (res == 0) delete this; return res; }

Единственной отличительной особенностью этих трех методов (кроме их имен) является то, что InternalQueryInterface при запросе IUnknown возвращает указатель на неделегирующую Unknown. Это просто требование Спецификации СОМ, которого следует придерживаться.

И наконец, подпрограмму создания Car требуется модифицировать для поддержки агрегирования:




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