Читаем Сущность технологии СОМ. Библиотека программиста полностью

Интерфейсы на базе IDispatch (часто называемые dispinterface – диспинтерфейс, или диспетчерский интерфейс ) логически эквивалентны обычному интерфейсу СОМ. Основное различие состоит в методах вызова на практике логических операций интерфейса. В случае обычного интерфейса СОМ вызовы методов основываются на статике, на априорном знании сигнатуры методов интерфейса. В случае диспинтерфейса вызовы методов основаны на текстовых представлениях ожидаемой сигнатуры вызовов методов. Если вызывающая программа правильно угадывает сигнатуру метода, то вызов может быть правильно диспетчеризован. Если же вызывающая программа неправильно угадывает сигнатуру метода, то диспетчеризовать вызов, возможно, не удастся. Если для параметров метода используются неверные типы данных, то преобразование их в нужные является делом объекта (если это вообще возможно).

Простейший способ выразить диспинтерфейс на IDL – это использовать ключевое слово dispinterface:

[uuid(75DA6450-DD0F-11d0-8C58-0880C73925BA)] dispinterface DPrimeManager {

properties: [id(1), readonly] long MinPrimeOnMachine;

[id(2)] long MinPrime;

methods: [id(3)] long GetNextPrime([in] long n);

}

Этот синтаксис вполне читабелен; однако он предполагает, что вызывающая программа будет всегда обращаться к свойствам и методам объекта через IDispatch. История показала, что по мере развития программных сред этапа разработки и выполнения они часто становятся способными использовать обычные интерфейсы СОМ. Для обеспечения того, чтобы обращение к диспинтерфейсу было успешным и в будущих средах подготовки сценариев, как правило, лучше моделировать интерфейс как двойственный, или дуальный (dual interface).

Двойственные интерфейсы являются обычными интерфейсами СОМ, наследующими от IDispatch. Поскольку IDispatch является базовым интерфейсом, то он абсолютно совместим с полностью интерпретируемыми клиентами сценариев. В то же время этот интерфейс совместим вверх со средами, которые могут непосредственно связываться со статически определенным интерфейсом СОМ. Ниже приведено IDL-определение для двойственного варианта интерфейса DPrimeManager:

[object, dual, uuid(75DA6450-DD0F-11d0-8C58-0080C73925BA)] interface DIPrimeManager : IDispatch {

[id(1), propget]

HRESULT MinPrimeOnMachine( [out, retval] long *pval); [id(2), propput]

HRESULT MinPrime([in] longval);

[id(2), propget] HRESULT MinPrime([out, retval] long *pval);

[id(3)] long GetNextPrime([in] long n);

}

Заметим, что этот интерфейс наследует IDispatch, а не IUnknown. Также отметим, что данный интерфейс имеет атрибут [dual] . Этот атрибут заставляет сгенерированную библиотеку типов включить в себя диспетчерский вариант интерфейса, который совместим со средами, не поддерживающими двойственные интерфейсы. Атрибут [dual] относится к категории атрибутов [oleautomation] и также заставляет сгенерированную библиотеку типов добавлять ключи реестра для универсального маршалера во время выполнения RegisterTypeLib.

Если интерфейс определен как двойственный, то реализация методов IDispatch является тривиальной. Дело в том, что синтаксический анализатор библиотеки типов реализует два из четырех методов IDispatch . Если двойственный интерфейс был определен заранее, объекту необходимо на этапе инициализации просто загрузить библиотеку типов: class PrimeManager:

DIPrimeManager { LONG m_cRef;

// СОМ reference count

// счетчик ссылок СОМ ITypeInfo *m_pTypeInfo;

// ptr. to type desc.

// указатель на описание типов

// IUnknown methods…

// методы IUnknown…

// IDispatch methods…

// методы IDispatch…

// IPrimeManager methods…

// методы IPrimeManager…

PrimeManager(void) : m_cRef(0) {

ITypeLib *ptl = 0;

HRESULT hr = LoadRegTypeLib(LIBID_PrimeLib, 1, 0, 0, &ptl);

assert(SUCCEEDED(hr));

hr = ptl->GetTypeInfoOfGuid(IID_DIPrimeManager, &m_pTypeInfo);

ptl->Release(); } virtual PrimeManager(void) { m_pTypeInfo->Release(); }

};

Имея приведенное выше определение класса, метод GetTypeInfo просто возвращает описание данного интерфейса:

STDMETHODIMP PrimeManager::GetTypeInfo (UINT it, LCID lcid, ITypeInfo **ppti) {

assert(it == 0 && ppti != 0);

(*ppti = m_pTypeInfo)->AddRef();

return S_OK;

}

Если бы объект поддерживал несколько локализованных библиотек типов, то реализации следовало бы использовать параметр LCID, чтобы решить, какое описание типа нужно возвратить. Соответствующая реализация GetTypeInfoCount еще проще:

STDMETHODIMP PrimeManager::GetTypeInfoCount(UINT *pit) {

assert(pit != 0); *pit = 1;

// only 0 or 1 are allowed

// допускаются только 0 или 1

return S_OK;

}

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных
Язык программирования Euphoria. Справочное руководство
Язык программирования Euphoria. Справочное руководство

Euphoria (юфо'ри, также рус. эйфори'я, ра'дость) — язык программирования, созданный Робертом Крейгом (Rapid Deployment Software) в Канаде, Торонто. Название Euphoria — это акроним для «End-User Programming with Hierarchical Objects for Robust Interpreted Applications».Euphoria — интерпретируемый императивный язык высокого уровня общего назначения. C помощью транслятора из исходного кода на Euphoria может быть сгенерирован исходный код на языке Си, который в свою очередь может быть скомпилирован в исполнияемый файл или динамическую библиотеку при помощи таких компиляторов, как GCC, OpenWatcom и др. Программа Euphoria также может быть «связана» с интерпретатором для получения самостоятельного исполняемого файла. Поддерживается несколько GUI-библиотек, включая Win32lib и оберток для wxWidgets, GTK+ и IUP. Euphoria имеет встроенную простую систему баз данных и обертки для работы с другими типам баз данных.[Материал из Википедии]

Коллектив авторов

Программирование, программы, базы данных