Інтерфейс > Диспетчерські інтерфейси дозволяють клієнтським програмам, написаним різними мовами, звертатися до СОМ-об’єктів. Давайте, наприклад, розглянемо мову сценаріїв типу Microsoft Visual Basic Scripting Edition (VBScript) , що використовується створення екземплярів СОМ-компонентів, написаних на C++ . У VBScript немає суворого контролю відповідності типів, і багато типів C++ йому невідомі. Щоб клієнт на VBScript міг успішно зв’язатися з сервером, Ви повинні надати йому диспетчерський інтерфейс (dispatch interface). Для цього достатньо реалізувати стандартний СОМ-інтерфейс IDispatch.
На цьому кроці ми розглянемо інтерфейс IDispatch.
Раніше ми говорили, що диспетчерські інтерфейси використовують технологію Automation для забезпечення взаємодії компонентів, написаних різними мовами програмування.
Починаючи з цього кроку, ми поговоримо про те, як використовуються інтерфейс IDispatch і тип даних VARIANT для отримання доступу до СОМ-компонентів, відмінних від C++ мов. А також про те, як клієнти, написані підтримуваними Microsoft мовами, наприклад Visual Basic або Microsoft Visual J++, звертаються безпосередньо до інтерфейсів компонентів, не вдаючись до диспетчерських механізмів.
Інтерфейс > Диспетчерські інтерфейси дозволяють клієнтським програмам, написаним різними мовами, звертатися до СОМ-об'єктів. Давайте, наприклад, розглянемо мову сценаріїв типу Microsoft Visual Basic Scripting Edition (VBScript) , що використовується створення екземплярів СОМ-компонентів, написаних на C++ . У VBScript немає суворого контролю відповідності типів, і багато типів C++ йому невідомі. Щоб клієнт на VBScript міг успішно зв'язатися з сервером, Ви повинні надати йому диспетчерський інтерфейс (dispatch interface). Для цього достатньо реалізувати стандартний СОМ-інтерфейс IDispatch.
На малюнку 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 в методи компонента. Крім того, вона відповідає за розпакування параметрів з масиву VARIANT та їх коректну передачу відповідному методу. Необхідно, щоб всі значення, що повертаються були упаковані в об'єкт, на який вказує VARIANT , для подальшої передачі назад клієнту.
На наступному кроці ми розглянемо тип даних VARIANT.