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



Двоичная композиция


Композиция и отделяемые интерфейсы — это две технологии на уровне исходного кода, предназначенные для реализации объектов СОМ на C++. Обе эти технологии требуют, чтобы разработчик объекта имел определения для каждого класса композита или отделяемого интерфейса в исходном коде C++, для возможности обработать подобъект, прежде чем возвратить его посредством QueryInterface. Для ряда ситуаций это очень разумно. В некоторых случаях, однако, было бы удобнее упаковать многократно используемую реализацию одного или большего числа интерфейсов в двоичный компонент, который мог бы обрабатываться через границы DLL, не нуждаясь в исходном коде подкомпонента. Это позволило бы более широкой аудитории повторно использовать подкомпонент, избегая слишком тесной связи с ним, как в случае повторного использования на уровне исходного кода (этот случай описан в главе 1). Однако если компонент повторного использования представляет собой двоичный композит или отделяемый интерфейс, то он должен участвовать в общей идентификации объекта.

Для полного охвата проблем, относящихся к унифицированию идентификации через границы компонентов, рассмотрим следующую простую реализацию ICar:

class Car : public ICar { LONG m_cRef; Car(void) : m_cRef(0) {} STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP GetMaxSpeed(long *pn); STDMETHODIMP Brake(void); };

STDMETHODIMP Car::QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(this); 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; }

// car class object's IClassFactory::CreateInstance // интерфейс IClassFactory::CreateInstance // объекта класса car STDMETHODIMP CarClass::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv) { Car *pCar = new Car; if (*pCar) return (*ppv = 0), E_OUTOFMEMORY; pCar->AddRef(); HRESULT hr = pCar->QueryInterface(riid, ppv); pCar->Release(); return hr; }




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