Повторное использование СОМ-объектов. Агрегация

   
На этом шаге мы рассмотрим основные моменты использования агрегации.

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

   
На рисунке 1 показано, как при агрегации предоставляется интерфейс внутреннего объекта.


Рис.1. Агрегация в COM

   
Дабы агрегация работала, внутренний объект должен быть агрегируемым (aggregatable), то есть
его надо создавать в расчете на поддержку агрегации. Поскольку клиентам внешнего объекта теперь доступны указатели
на интерфейс внутреннего объекта, они могут вызывать методы IUnknown внутреннего объекта. А так как
последний не способен обслуживать вызовы QueryInterface(), AddRef() и Release() от имени внешнего,
клиентские вызовы интерфейса IUnknown внутреннего объекта надо переадресовывать в IUnknown внешнего
объекта, который называется управляющим стандартным интерфейсом (controlling unknown).

   
Примечание.
Имейте в виду, что клиент агрегированного объекта ничего не знает об агрегации - с его точки зрения, это всего лишь
деталь реализации. Клиент "видит" единственный СОМ-объект с единственным указателем на IUnknown;
получая указатели на интерфейсы внутреннего объекта, считает их принадлежащими внешнему объекту.

   
Когда внешний объект создает внутренний, он использует второй параметр функции CoCreateInstance(), передавая
фабрике классов внутреннего объекта адрес управляющего стандартного интерфейса. Если этот адрес не NULL, внутренний
объект узнает, что он агрегирован, и начнет посылать запросы метода IUnknown в управляющий стандартный интерфейс.

   
Но внутренний объект должен уметь различать вызовы методов IUnknown, приходящие от внешних клиентов
(и направляемые управляющему стандартному интерфейсу), от вызовов методов IUnknown, приходящих от
управляющего стандартного интерфейса (которые используются внешним объектом для нахождения интерфейсов и
управления существованием агрегированного объекта). А это означает, что агрегируемый СОМ-объект должен
предоставлять две версии интереса IUnknown:

  • делегируемую (delegating) и
  • неделегируемую (nоndelеgating).

   
Внешний компонент вызывает неделегируемые методы IUnknown, а внешние клиенты - делегируемые методы.
Последние пересылают запросы в управляющий стандартный интерфейс, если объект агрегирован, и в неделегируемый
IUnknown, если объект не агрегирован.

   
На следующем шаге мы рассмотрим реализацию агрегации с помощью ATL.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий