Шаг 156.
Среда программирования Visual C++.
Архитектура СОМ. Диспетчерские интерфейсы. Интерфейс IDispatch

    На этом шаге мы рассмотрим интерфейс IDispatch.

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

    Начиная с этого шага мы поговорим о том, как используются интерфейс IDispatch и тип данных VARIANT для получения доступа к СОМ-компонентам из отличных от C++ языков. А также о том как клиенты, написанные на поддерживаемых Microsoft языках, например Visual Basic или Microsoft Visual J++, обращаются напрямую к интерфейсам компонентов, не прибегая к диспетчерским механизмам.

Интерфейс IDispatch

    Диспетчерские интерфейсы позволяют клиентским приложениям, написанным на различных языках, обращаться к СОМ-объектам. Давайте, к примеру, рассмотрим язык сценариев типа Microsoft Visual Basic Scripting Edition (VBScript), используемый для создания экземпляров СОМ-компонентов, написанных на C++. В VBScript нет строгого контроля соответствия типов, и многие типы из C++ ему неизвестны. Чтобы клиент на VBScript мог успешно связаться с сервером Вы обязаны предоставить ему диспетчерский интерфейс (dispatch interface). Для этого достаточно реализовать стандартный СОМ-интерфейс IDispatch.

    Иногда требуется создать СОМ-объекты, доступные исключительно клиентам на C++. Например, к этой категории относятся объекты, созданные компанией-разработчиком для внутреннего пользования. В этом случае не придется тратить усилия на реализацию IDispatch. Тем не менее, если Вы хотите, чтобы Ваш объект был доступен из более широкого диапазона языков, Вам придется создать этот интерфейс. Клиенты, написанные на языках, поддерживаемых Microsoft (например, Visual Basic), все равно в состоянии применять СОМ-компоненты на C++ без интерфейса IDispatch. Но это возможно при условии, что они используют интерфейсы, обменивающиеся только параметрами, которые поддерживаются Automation. К ним относятся параметры таких типов данных, которые можно упаковать в стандартный формат данных VARIANT - определенный в СОМ тип объединения.

    На рисунке 1 показано, как можно реализовать интерфейс IDispatch для класса Encoder.


Рис.1. Реализация интерфейса IDispatch

    Таблица vtable объекта Encoder содержит указатели на функции, реализованные в IDispatch. Клиентское приложение может запускать метод GetIDsOfNames(), передавая имя метода в виде строки, например "Encode". В методе GetIDsOfNames() создается внутренняя таблица, которая связывает имя каждого метода с числовым диспетчерским идентификатором - он называется Dispatch ID, или DISPID - это просто число; в примере на рисунке 1 DISPID функции Encode равен 1.

    Получив DISPID требуемого метода, для его запуска клиентское приложение вызывает Invoke(). Диспетчерский идентификатор, возвращенный GetIDsOfNames(), передается в качестве параметра при вызове метода Invoke(). Кроме того, в него передаются параметры для вызываемых методов, упакованные в массив переменных типа VARIANT, а также указатель на переменную типа VARIANT, в которую будут помещены значения, возвращаемые вызываемым методом.


    Примечание. Здесь показана упрощенная модель процесса дисппетчеризации. Параметры для вызываемых методов могут быть также поименованы и обладать собственными идентификаторами Dispatch ID.

    Созданная Вами версия Invoke() вызывает нужный метод от имени клиента Automation и должна содержать таблицу для перевода значений DISPID в методы компонента. Кроме того, она отвечает за раcпаковку параметров из массива VARIANT и их корректную передачу соответствующему методу. Необходимо, чтобы все возвращаемые значения были упакованы в объект, на который указывает VARIANT, для дальнейшей передачи обратно клиенту.

    На следующем шаге мы рассмотрим тип данных VARIANT.




Предыдущий шаг Содержание Следующий шаг