Общие сведения о технологии COM

В начале 90-х годов минувшего века фирмой Microsoft была предложена технология OLE 1.0 (Object Linking and Embedding - связывание и внедрение объектов). В основу OLE 1.0 были положены механизмы динамического обмена данными (DDE). Она основывалась на концепции составных документов (compound documents). С точки зрения пользователя, такой документ выглядит единым набором информации, но фактически содержит элементы (фрагменты) более чем одного типа (т. е. созданные разными приложениями, например, текст и графику). Эта технология фактически предложила документно-ориентированную модель работы с компьютером - "пользователь должен больше думать об информации и меньше - о приложениях, ее обрабатывающих". Технология изначально разрабатывалась как средство интеграции приложений пакета MS Office, обеспечивающее взаимодействие между его компонентами (Excel, Word, Power Point и т.п.) [ ].

Как и в большинстве случаев, первая версия OLE не была совершенна. И в следующей версии OLE претерпела глобальные изменения. Разработчиками была создана группа технологий, область применения которых выходила за рамки составных документов. Основой этих технологий стала COM - Component Object Model (модель компонентных объектов). На этом фундаменте была построена более совершенная версия продукта - OLE2, появившаяся в мае 1993 года.

OLE2 объявила новый стандарт, который позволил создавать не только составные документы, но и регламентировать общие правила взаимодействия любых типов программ. Отныне все новые технологии, основанные на COM, получили общее название – OLE - Microsoft более не рассматривала данный термин как аббревиатуру, также было решено опустить номер версии. Однако, в дальнейшем, начиная с операционной системы Windows 95 (и старше), технология COM стала базовой технологией Windows, которую, сегодня можно рассматривать как систему, состоящую из нескольких тысяч "кирпичиков" – COM-объектов. Причем, эти COM-объекты доступны не только средствам операционной системы, но и любым другим программным средствам, поддерживающим стандарт OLE2. Для корпоративной ОС Windows NT в 1996 году Microsoft разработала распределенную СОМ (Distributed СОМ - DCOM), которая позволяла клиенту создавать и использовать объекты, как на удаленных системах, так и на локальной. Более того, клиент может даже не осознавать различия между этими двумя случаями. С появлением Internet, технология COM нашла свою нишу и здесь под именем ActiveX [12] (одно время эту технологию называли OLE3). Постепенно ActiveX стала отвоевывать пространства исконно занятые OLE, и сегодня все вернулось на круги своя - термин OLE относится только к технологии создания составных документов, и применяется, в основном, при автоматизации и интеграции компонентов пакета MS Office. а на основе технологии COM, помимо OLE и ActiveX, создан ряд других технологий – DirectX, Microsoft Agent и т. п.

технология СОМ+ появилась в конце 1998 года, и, представляет собой дальнейшее развитие компанией Microsoft новой генерации технологии СОМ для корпоративной ОС Windows 2000. Ее можно рассматривать как дальнейшее развитие DCOM, предоставляющее множество новых возможностей, включая управление объектами во время выполнения и основанный на языках программирования инструментарий.

В настоящее время фирмой Microsoft активно внедряется кросплатформенная архитектура.net. Поскольку технология СОМ ориентирована на работу в среде Windows, то первоначально казалось, что при таком подходе фирма вынуждена будет отказаться от поддержки этой технологии. Однако Microsoft выпустила специальный документ, разъясняющий, что .NET Framework основывается на тех же базовых компонентных сервисах, что и COM+: транзакции, очереди, пулы объектов. Естественно, что существующие ныне возможности технологии COM+ будут при этом существенно расширены. При этом в .NET сохранится возможность использования COM-объектов в "старом стиле". Причем во многих случаях, можно выполнить преобразование из объекта COM в .NET и обратно.

2.3 Основы COM-технологии

Основные понятия COM-технологии

COM (Component Object Model) - модель объектных компонентов - одна из основных технологий, на которых основывается Windows. Более того, все новые технологии в Windows (Shell, Scripting, поддержка HTML и т.п.) реализуют свои API именно в виде COM-интерфейсов. Таким образом, в настоящее время профессиональное программирование требует понимания модели COM и умения с ней работать.

Спецификация СОМ (СОМ Specification) - это документ, который устанавливает стандарт для компонентной архитектуры. Он содержит указания о том, как создавать динамически взаимозаменяемые компоненты. СОМ определяет стандарт, которому должны следовать компоненты и клиенты, чтобы гарантировать возможность совместной работы. Стандарты важны для компонентных архитектур так же, как и для любой системы с взаимозаменяемыми частями. Стандарты особенно важны, когда разные части системы разрабатывают разные люди из разных организаций в разных странах. Без стандартов ничто не могло бы работать вместе.

Технология СОМ работает с так называемымиСОМ-объектами. СОМ-объекты похожи на обычные "классические" объекты использующиеся в современном программировании, однако отличаются от них тем, чтово-первых, вдобавок ко всем обычным свойствам имеетидентификатор класса (CLSID), аво-вторых- это полностью закрытые данные, которые могут быть полученытолько через некую функцию-метод. Набор таких методов, позволяющий работать с данными объекта, носит названиеинтерфейса. Клиенты могут получитьдоступ к сервисам объекта СОМ только через вызовы методов интерфейсов объекта- у них нет непосредственного доступа к данным объекта. Обычный СОМ-объект включает в себя один или несколькоинтерфейсов. Каждый из этих интерфейсов имеет собственный указатель.

5.3.2 Структура компонентов COM

В СОМ любая часть программного обеспечения реализует свои сервисы как один или несколько объектов СОМ. Компонент, соответствующий модели COM, состоит из собственно объекта COM и интерфейсов COM. Каждый такой объект поддерживает один или несколько интерфейсов, состоящих из методов.

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

Интерфейс- это набор методов, позволяющий работать с данными объекта. Согласно венгерской нотации, имена всех интерфейсов начинаются с буквы I.Все интерфейсы строятся (наследуются) от базового интерфейса, который называется lUnknown ("неизвестный"). Несмотря на такое название, это единственный интерфейс, о котором знают все клиенты и компоненты, а такое название объясняется тем, что поскольку все интерфейсы COM являются его наследниками, то при наличии у клиента указателя на lUnknown, он может запросить через него другие интерфейсы даже в том случае, если он не знает указателями на какой именно интерфейс обладает данный объект. Интерфейс lUnknown имеет всего три метода:AddRef, прибавляющий единицу к счетчику блокировок объекта,Release, вычитающий единицу из счетчика блокировок, иQuerylnterface, который позволяет найти указатель на другой интерфейс объекта, если таковой имеется.Querylnterfaceнаходит указатель натаблицу виртуальных методов, которая хранит указатели на методы интерфейса.

В COM интерфейсом является определенная структура в памяти, содержащая массив указателей на функции. Каждый элемент массива содержит адрес функции, реализуемой компонентом. Именно эта структура в памяти и является интерфейсом с точки зрения COM, а все остальное - детали реализации, которые COM не касаются. На рис. 2.1а показана комплексная схема интерфейса.

На практике такая схема не применяется, а сворачивается до вида, показанного на рис. 2.1б Интерфейс на ней изображен кружком, который называется гнездом (Jack).

Большинство объектов СОМ поддерживают более одного интерфейса. Например, если некоторый объект СОМ, представляетВаш счет в банке, то к одному из интерфейсов вы можете иметь непосредственный доступ, и он содержит методы Deposit (Положить-НаСчет), Withdrawal (СнятьСоСчета) и CheckBalance (ПроверитьОстаток). Однако тот же объект может поддерживать и другой интерфейс, содержащий методы вроде ChangeAccountNumber (ИзменитьНомерСчета) и CloseAccount (ЗакрытьСчет), которые могут вызываться только сотрудниками банка. При этом, каждый интерфейс может содержать методы, связанные друг с другом.

Общие сведения о технологии COM - student2.ru
На рис 2.2 показан объект COM. Сам объект всегда реализуется внутри некоторого сервера (прямоугольник вокруг объекта). Сервер может быть либо динамически подключаемой библиотекой (DDL), подгружаемой во время работы приложения, либо отдельным самостоятельным процессом.

Общие сведения о технологии COM - student2.ru Что бы вызвать методы интерфейса COM, клиент должен получить указатель на этот интерфейс. Обычно COM-объект предоставляет свои сервисы посредством нескольких интерфейсов, и клиенту требуется отдельный указатель для каждого интерфейса, методы которого он намерен вызывать.

5.3.3 Основные принципы построения COM-объектов

1. Нахождение объекта COM. Любой COM-объект не может существовать независимо. Он может быть реализован только сервером объектов COM. Сервер отвечает за создание, существование и уничтожение своих объектов COM. Каждый COM-объект "живет" в адресном пространстве своего сервера.

2. Фундаментальный интерфейс. Любой COM-объект всегда содержит интерфейс IUnknown. Так же этот интерфейс является предком (может быть и не прямым) любого интерфейса. При создании COM-объекта чаще всего возвращается ссылка именно на этот интерфейс. Этот интерфейс содержит всего три метода:

- QueryInterface - посредством этого метода можно получить ссылку на любой другой интерфейс объекта. При вызове этого метода автоматически выполняется так же метод AddRef.

- AddRef - увеличивает счетчики ссылок внутри COM-объекта и сервера. Счетчики ссылок необходимы, что бы объект и сервер знали, когда можно закончить работу и освободить используемые ресурсы. При любом дублировании указателя на интерфейс внутри клиента необходимо вызывать этот метод, что бы ни возникло ситуации, когда клиент пытается выполнить метод COM-объекта, когда тот уже не существует.

- Release - уменьшает счетчики ссылок внутри COM-объекта и сервера. Этот метод вызывается клиентами каждый раз, когда ссылка на какой-нибудь интерфейс больше не нужна. При достижении нуля счетчиком ссылок COM-объекта этот объект перестает существовать, а при достижении нуля счетчиком ссылок сервера он (как правило) полностью выгружается, освобождая ресурсы системы.

Так как IUnknown является предком всех интерфейсов, то все интерфейсы содержат эти три метода, и, следовательно, имея ссылку на любой интерфейс COM-объекта можно получить ссылку на любой другой интерфейс этого же объекта.

Общие сведения о технологии COM - student2.ru 3. Наследование. Объекты COM поддерживают наследование, но лишь на уровне интерфейсов. Данное ограничение вполне уместно, если вспомнить, что COM-объект представляет собой некий черный ящик, детали реализации которого известны лишь его создателю. В связи с этим если бы существовало наследование на уровне реализации, то могла бы возникнуть ситуация, когда объект, а именно его наследуема часть, поведет себя совсем не так, как ожидает программист, что может привести к сбою или краху системы. Один интерфейс может быть предком для нескольких других интерфейсов. При этом создается как бы дерево наследования, но корнем этого дерева всегда является интерфейс IUnknown. Следует отметить, что на самом деле существует способ создать иллюзию наследования реализации путем включения или путем агрегирования объекта.

 
  Общие сведения о технологии COM - student2.ru

4. Неизменность интерфейсов. В создании COM-объектов есть одно "железное" правило, соблюдать которое обязан каждый программист, создающий и, главное, поддерживающий свой объект COM:

Возможно создание в новой версии объекта нового интерфейса с дополнительными методами. Допустим, если есть некий интерфейс IInterface, то можно создать новый интерфейс IInterface2 путем наследования IInterface и добавления к нему новых методов. Это правило связано, отчасти, с тем, что к моменту модификации вашего объекта уже, возможно, будут существовать десятки или даже сотни (если повезет) приложений-клиентов, использующих этот объект со старыми интерфейсами. Естественно так же не должен меняться IID существующих интерфейсов.

2.3.4 Основные принципы организации интерфейсов.

Интерфейс - это своего рода договор между объектом и клиентом. Для того чтобы использовать интерфейс клиент и объект должны договориться между собой о следующих вещах:

- как идентифицировать интерфейс в системе;

- об общем способе описания интерфейса;

- о конкретной его реализации.

Идентификация интерфейса происходит через его имя. Каждый интерфейс имеет по два имени: символьное, предназначенное для людей, и имя в виде шестнадцати байтного кода - предназначенное для использования программным обеспечением. Символьное имя может дублироваться в разных интерфейсах, имя же, используемое программами, по определению, должно быть уникально. По соглашению символьные имена интерфейсов должны начинаться с буквы I (от Interface). Символьные имена удобны при упоминании их в литературе или разговоре, но они не годятся когда клиент должен точно указать объекту, какой интерфейс ему нужен.

Для этого у интерфейса есть уникальное имя - глобальный уникальный идентификатор - GUID (globally unique identifier). GUID произносится обычно как "гуид" или "гвид". Первоначально разработчики GUID использовали вместо него термин универсальный уникальный идентификатор - UUID (universally unique identifier), который иногда можно встретить в программах и документации. GUID интерфейса называется идентификатором интерфейса - IID (interface identifier) и представляет собой шестнадцатибайтовый код (128 бит), обычно генерируемый программой (например, программами uuidgen.exe (командная строка) и диалоговой guidgen.exe, входящими в комплект поставки языка VC++ фирмы Microsoft). Исходный текст последней можно найти в документации по VC++. В основе этих программ лежит вызов функции CoCreateGuid библиотеки COM Microsoft (ее можно вызвать и из Delphi), которая в свою очередь вызывает функцию RPC UuidCreate. Следует отметить, что нет никакой организации, регистрирующей глобальные идентификаторы - их уникальность во времени и пространстве обеспечивается за счет уникальности системы, на которой они были созданы. Уникальность во времени гарантируется внутренними часами компьютера, а уникальность в пространстве гарантируется или за счет сетевой платы, установленной на машине (каждая сетевая плата имеет шести байтовый уникальный адрес: различные диапазоны адресов выделяются фирмам, производящим сетевые платы, и каждой плате, произведенной фирмой, присваивается свой адрес из этого диапазона), или, при ее отсутствии, генерируется из различных уникальных параметров компонентов системы (номер материнской платы, BIOS и др.). Используемый в настоящее время алгоритм генерации GUID начнет выдавать повторяющиеся значения примерно в 3400 году.

Спецификация интерфейсанеобходима для получения информации о типах, т.е. о существующих в интерфейсе методах и типов их параметров. Для описания интерфейса COM-объекта нет определенных стандартов - это может быть чистый C++, Delphi или какой-нибудь упрощенный вариант какого-либо языка. Наличие описания интерфейса позволяет использовать методы COM-объекта посредством вызовов их черезтаблицу виртуальных функций (v-table). Иногда ее просто называют виртуальной таблицей. Она аналогична VMT в TP или Delphi. При наличии у COM-объекта дуального или диспинтерфейса можно вызвать метод объекта и не зная весь интерфейс, но это приводит к определенным накладным расходам. И все же наличие какого-либо общего языка для спецификации интерфейсов позволяет существенно упростить процесс создания клиентов COM-объектов. И такой язык существует - это язык описания интерфейсов - IDL (Interface Definition Language). На IDL можно написать полную и точную спецификацию интерфейса объекта COM.

Реализация интерфейсаопределяет двоичный формат, поддерживаемый COM-объектом для каждого интерфейса. Наличие такого стандарта позволяет осуществить вызов методов интерфейса независимо от языка, на котором написаны COM-объект и клиент. Вызов методов производится посредством использования v-table, отвечающей стандартам языка C++.

Классы.Любой COM-объект является экземпляром некоторого класса, и каждому классу может быть присвоен GUID - идентификатор класса -CLSID (class identifier).При создании экземпляра класса клиент вызывает функцию из библиотеки COM и передает ей в качестве параметра идентификатор класса. Но класс не обязательно должен иметь идентификатор - экземпляр класса может создаваться и без помощи библиотеки COM. Одновременно может существовать сколько угодно экземпляров класса, и каждый из них представляет собой автономный полнофункциональный COM-объект. Класс представляет собой реализацию набора интерфейсов COM-объекта, а CLSID является идентификацией некоторого фрагмента кода для создания и инициализации объектов посредством библиотеки COM.

2.4 Использовании COM-объектов для разработки интегрированных средств программного обеспечения.

Наши рекомендации