Рефераты. Разработка приложений в рамках COM

Альтернативой рассмотренному методу может служить вызов глобальной API-функции CoCreateInstance, которая выполняет перечисленный выше действия и создает объект класса с идентификатором CLSID, но таким образом можно создать только один объект данного класса, т.к. функция не возвращает указатель на интерфейс производителя классов.


2.7.           Библиотеки типов


Библиотека типов (type library) предоставляет информацию об используемых типах объектов и интерфейсах, которые предоставляются ActiveX-серевером. Библиотека типов по смыслу аналогична, например, заголовочному файлу (header) для разработок на языке C и любому другому модулю, содержащему информацию об используемых типах данных и объектах. Большинство информации подобного рода может быть записано в библиотеку типов. Получить информацию из библиотеки типов можно путем опроса запущенного объекта или же посредством загрузки непосредственно библиотеки типов. После создания библиотеки типов, к ней обеспечивается доступ через специальный тип интерфейсов: ITypeLib, ITypeInfo и ITypeComp. Интерфейс ITypeLib обеспечивает доступ к информации о типах в библиотеке типов, а также к описаниям конкретных объектов, которые, в свою очередь, могут быть получены через интерфейс ITypeInfo.

Библиотека типов содержит информацию о том, какой интерфейс, в каком COM-объекте содержится, количество и тип методов интерфейсов и их параметров. Эти описания включают в себя уникальные идентификаторы классов (CLSID) и их интерфейсов (IID), через которые осуществляется корректный доступ к объектам. В библиотеке типов также может содержаться следующая информация:

·        Описания пользовательских типов данных, связанных с пользовательскими интерфейсами;

·        Функции, которые экспортируются ActiveX-сервером, но которые не являются интерфейсными методами;

·        Информация об энумерованных типах данных (символьных константах);

·        Ссылки на описания типов в других библиотеках типов.


Использование библиотеки типов очень важно для объектов, которые предназначены для распространения и последующего использования многими пользователями. Также существует еще ряд причин использования библиотек типов:

·             Объекты, которые используют непосредственную привязку к vtable, должны быть описаны в библиотеке типов, т.к. ссылки в vtable формируются во время компиляции;

·             Объекты, созданные из классов, которые поддерживают интерфейс IProvideClassInfo, должны иметь библиотеку типов. Объекты, имеющие в своем составе данные интерфейс, являются типизированными COM-объектами, т.к. предоставляют информацию об используемых типах (из библиотеки типов);

·             Элементы управления ActiveX должны иметь библиотеку типов, которая содержится непосредственно в DLL или OCX файле, содержащем код ActiveX-сервера;

·             Приложения, которые являются Automation-серверами, должны иметь библиотеку типов, для более удобно связывания с клиентами;

·             Использование библиотеки типов в любом случае облегчает работу с внешними приложениями, которые могут узнать об используемых типах данных, и т.о. исключается использование более громоздкого метода передачи параметров в системе через универсальный механизм;


2.8.           Диспетчерский интерфейс


Диспетчерский интерфейс (dispatch interface) – стандартная специальная реализация интерфейса IDispatch, которую предлагает COM. Данная реализация обеспечивает выполнение процедур позднего связывания (late binding) и маршаллинга. Диспетчерский интерфейс хранит внутри себя таблицу диспетчерских идентификаторов (dispID), каждый из которых является уникальным идентификатором члена интерфейса, и таблица, по сути, реализует отображение соответствующего dispID на имя каждого члена интерфейса. Клиент, желающий получить доступ к ресурсу сервера (к методу или к свойству), должен знать dispID для соответствующего ресурса. Такую информацию можно получить через вызов метода интерфейса IDispatch, который называется GetIDsOfNames, и который является первой записью в vtable для интерфейса IDispatch. Таким образом, клиент получает информацию типах данных, используемых сервером, и получает таблицу диспетчерских идентификаторов, с отображением имени каждого ресурса сервера на соответствующий dispID. Данная операция и со стороны клиента, и со стороны сервера, при использовании стандартной реализации интерфейса IDispatch реализуется автоматически. Эта процедура называется поздним связыванием, т.к. осуществляется на этапе выполнения программы, а не на этапе компиляции. Имея для каждого имени ресурса сервера соответствующий dispID, клиент может осуществить обращение к нему, используя метод интерфейса dispID, который именуется Invoke. Метод Invoke имеет сигнатуру, допускающую вызов с любым количеством параметров, чем обеспечивается его универсальность. Реализация Invoke распаковывает параметры и осуществляет вызов соответствующего метода или свойства и осуществляет контроль над выдачей исключений при выполнении метода или свойства. Когда выполнение метода или обработка свойства заканчивается, возвращаемые значения метода или свойства отправляются обратно клиенту. Если обращение клиента к серверу переходит через границы процесса или машины, то автоматически реализуются все действия по организации маршаллинга. Такая прозрачность является основным достоинством использования интерфейса диспетчеризации.

Основным недостатком диспетчерского интерфейса является ограничение на типы данных, которые можно использовать при передаче параметров. Это следует из необходимости упаковки и распаковки параметров при осуществлении маршаллинга. Допускается использовать 13 стандартных типов данных. На пользовательские типы данных устанавливаются достаточно строгие ограничения. Если требования задачи не укладываются в эти ограничения, разработчик имеет возможность реализовать маршаллиг, путем написания своего proxy/stub кода. Еще одним недостаток проявляется в том, что при компиляции программы не выполняется проверка соответствия типов вызываемых функций, т.к. связывание диспетчерских интерфейсов осуществляется на этапе выполнения программы, и таким образом, не контролируется вызов Invoke с неверным набором аргументов, что вызывает ошибку выполнения.


2.9.        Привязка идентификаторов


COM предлагает возможность привязки диспетчерских интерфейсов на этапе компиляции. Если объект описан в библиотеке типов, то dispID может быть прочитан для каждого ресурса объекта, т.к. dispID является для каждого метода или свойства фиксирован, и является частью описания используемых типов данных объекта. Такая процедура называется привязкой идентификаторов (ID bindig). Метод GetIDsOfNames вызывается компилятором во время трансляции программы, таким образом, привязка идентификаторов является формой раннего связывания (early binding). В результате, на этапе выполнения, при первом вызове сервера клиентом, не требуется вызов процедуры привязки интерфейсов, что ускоряет работу. Еще одним достоинством данного подхода является проверка соответствия типов в обращениях к ресурсам сервера.

Основным недостатком является отсутствие возможности проверки имени ресурса, если он вдруг изменился. В клиентском объекте все вызовы будут осуществляться через однажды связанные на этапе компиляции интерфейсные идентификаторы.


2.10.  Пользовательские интерфейсы


Vtable-интерфейсы (vtable interfaces) или пользовательские интерфейсы - определяются пользователем, и допускают вызывать методы интерфейса, пользуясь ссылками из vtable, при условии, если известен порядок записи ссылок на методы, число и тип передаваемых аргументов. Первые три записи в vtable соответствуют трем методам интерфейса IUnkown, за которыми следуют ссылки на остальные поддерживаемые интерфейсы. Если объект не реализует диспетчерский интерфейс, то следом за IUnkown непосредственно следуют ссылки на методы пользовательских интерфейсов, то есть, становится возможно обращение к методам и свойствам объектов непосредственно через ссылки из vtable.

В случае если сервер имеет библиотеку типов и реализует диспетчерский интерфейс, то клиент может получить информацию из библиотеки типов, без осуществления вызова функций через привязки. Достаточно получить идентификаторы dispID диспетчерского интерфейса, и осуществить привязку непосредственно к vtable. Таким образом, можно осуществить более быстрый доступ к ресурсам объекта, осуществляя прямой вызов через ссылки в vtable, не используя диспетчерский интерфейс. Код непосредственной привязки к vtable может быть автоматически сгенерирован на этапе компиляции. Разумеется, такой метод вызова функций гораздо быстрее, чем методы привязки идентификаторов (т.к. вызов осуществляется через Invoke, что вызывает процедуры упаковки/распаковки параметров) и позднего связывания (т.к. осуществляется полный цикл работы с диспетчерским интерфейсом).




2.11.    Двойные интерфейсы


Несмотря на то, что COM предоставляет возможность обращения к ресурсам серверов используя vtable-интерфейсы, что повышает скорость взаимодействия клиента и сервера, некоторые клиенты могут быть разработаны таким образом, что обращаются к объектам только через интерфейс диспетчеризации. Это могут быть, например, интерпретируемые макроязыки, которые включают в себя средства для работы с COM-объектами, и в которых не реализованы возможности для привязки к vtable. Таким образом, COM предлагает то, что называется двойственным, или двойным интерфейсом (dual interface). Двойные интерфейсы предлагают два пути для доступа к ресурсам сервера: через диспетчерский интерфейс и через vtable-интерфейс. Двойной интерфейс определяется как наследник IDispatch.

Преимущества использования двойных интерфейсов:

·        Двойные интерфейсы предлагают возможность получения указателей на ресурсы сервера по их именам при компиляции объекта, таким образом, позволяя создавать клиентов, с привязкой к vtable на этапе компиляции;

Страницы: 1, 2, 3, 4



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.