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



         

Маршалер свободной поточной обработки (FreeThreaded Marshaler) - часть 2


Однако объект мог бы договориться со специальным заместителем о том, чтобы просто передать исходный указатель нужному объекту. Хотя данная технология безупречно работает для внутрипроцессного маршалинга, она, к сожалению, не приводит к успеху в случае межпроцессного маршалинга. Но, к счастью, реализация объекта может просто обратиться к стандартному маршалеру за другим контекстом маршалинга, отличным от 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.




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