Интерфейс IDispatch

В технологии СОМ предусмотрена возможность доступа к методам интерфейса при отсутствии информации о порядке реализации методов в виртуальной таблице. В этом случае среда разработки сохраняет текстовые названия методов в файле, в котором находится скомпилированный код СОМ-сервера. Это означает, что в СОМ-сервере реализован интерфейс IDispatch, который является центральным элементом технологии OLE Automation. Ключевыми методами этого интерфейса являются методы GetIdsOfNames и Invoke, которые позволяют клиенту получить у сервера ответ на вопрос, поддерживает ли он метод с указанным именем, а затем, если метод поддерживается, — вызвать его.

Опишем основной алгоритм вызова методов при помощи интерфейса IDispatch. Когда клиенту требуется вызвать какой-либо метод сервера, сначала он вызывает метод GetIdsOfNames интерфейса IDispatch, передавая ему имя запрошенного метода сервера. Если сервер поддерживает запрошенный метод, он возвращает его идентификатор — целое число, уникальное для каждого метода. После этого клиент упаковывает параметры в массив переменных типа OleVariant и вызывает метод Invoke, передавая ему массив параметров и идентификатор запрошенного метода.

Таким образом, все, что должен знать клиент, — это строковое имя метода. Такой алгоритм позволяет работать с наследниками интерфейса IDispatch из языков сценариев.

Реализация методов GetIdsOfNames и Invoke, предоставляемая СОМ по умолчанию, базируется на библиотеке типов объекта.

При работе с интерфейсом IDispatch связь между вызываемыми методами устанавливается при выполнении приложения. Такой способ вызова методов интерфейсов называют поздним связыванием (late binding). Для подобного вызова методов требуется провести большее число операций, чем при прямом обращении к виртуальной таблице, и это может сказаться на скорости выполнения вызовов. При отсутствии библиотеки типов на этапе разработки сервера невозможно проверить правильность написания имен методов и списков параметров методов. Это может обнаружиться только на этапе выполнения клиентского приложения — когда произойдет исключение. Поэтому клиентское приложение, работающее с сервером через интерфейс IDispatch, обязательно следует тестировать на предмет корректного выполнения всех команд.

Кроме того, при наличии библиотеки типов для реализации нотификационных сообщений (то есть уведомлений о событиях, которые СОМ-сервер посылает клиенту) в элементах управления ActiveX вывод этих сообщений возможен только через интерфейс IDispatch. Элемент управления ActiveX определяет интерфейс для поддержки нотификационных сообщений, но сам его не создает. Он должен быть реализован в клиенте, а элемент управления ActiveX должен получить ссылку на него и вызывать методы этого интерфейса в ответ на события, происходящие с ним. Поскольку СОМ-сервер следует компилировать раньше клиента, нет никакой возможности на этапе компиляции сервера получить доступ к таблице виртуальных методов клиента и связать нотификационные сообщения с методами, определенными в клиенте.