Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Технология COM

Содержание:

Введение

Технология COM появилась в попытке Microsoft стандартизировать компонентную коммуникацию.

Глава 1. Краткий обзор технологии COM

COM, по сути, является формальным способом использования таблиц C ++ vtables [1] из C и других языков, поэтому вы можете создавать и использовать компоненты на любом языке, а также перезванивать между ними. Это способ выразить рациональное подмножество того, как классы C ++ работают и форматируют в памяти, способом, который может быть реализован на других языках.

Это было результатом языковых войн C / C ++ / Visual Basic в Microsoft.

Первоначальная 16-разрядная версия Visual Basic версии 1–3 имела механизм расширения подключаемого модуля под названием VBX - Расширения Visual Basic [2].

Они были чрезвычайно популярны и стали жертвой собственного успеха после того, как вокруг них выросла целая индустрия, и люди начали использовать их для всех видов вещей, для которых они не предназначены, и хотели использовать их из других языков и сред, таких как Борланд. Microsoft пришлось что-то предпринять, чтобы смягчить катастрофу успеха VBX, поэтому они изобрели COM.

В то время Microsoft переходила с Win16 на Win32, поэтому они разработали 32-битное определение COM, также известное как OCX или OLE Controls, которое они позже назвали ActiveX, потому что COM было очень трудно найти, и они хотели отвлечь внимание от Java новым модным словом.

Таким образом, они создали кучу уродливых макрологий на Си, которые позволили программистам на Си (или мастерам Visual Studio) определять COM-интерфейсы в заголовочных файлах и файлах реализации, которые просто распределяли память точно так же, как таблицы виртуальных классов С ++.

В то время как программы на C ++ будут использовать другие некрасивые макросы для объявления реальных честных классов C ++ для реализации интерфейсов COM.

И программисты Visual Basic ... делали бы то, что делали программисты Visual Basic.

Метод COM IUnknown :: QueryInterface [4] по сути похож на C ++ dynamic_cast [5]. Но он также добавляет некоторые функции агрегации объектов [6], которые позволяют объединять несколько подобъектов вместе путем агрегации вместо использования монолитного наследования. Вы можете реализовать «отрывные интерфейсы» [7], которые лениво создают агрегированные подобъекты по запросу, что полезно для реализации интерфейсов обратного вызова.

MFC (Microsoft Foundation Classes) - это набор оболочек C ++ для низкоуровневых интерфейсов Win32, а также огромный каркас для реализации графических элементов и диалоговых окон поверх Win32 и для обертывания интерфейсов OLE-автоматизации rube-goldbergesque вокруг классов C ++. Некоторое время MFC был основным способом реализации COM-интерфейсов в C ++, но он был печально знаменит тем, что был ужасно сложным, со всеми его уродливыми макросами, венгерской нотацией и странными соглашениями о программировании.

Позже Microsoft выпустила библиотеку ActiveX Template Library (ATL), предназначенную только для C ++ [8], которая, хотя и была достаточно уродливой, представляла собой более элегантный и мощный способ реализации COM-компонентов в C ++, но у нее не было багажа. поддержки C, и позволит вам реализовать компоненты COM / OLE / ActiveX без отвратительной инфраструктуры MFC. ATL был популярен для реализации всевозможных плагинов Internet Explorer.

На самом деле OLE был слоем интерфейсов COM и MIDL (Microsoft Interface Definition Language) поверх COM, который добавляет интерфейс IDispatch для динамического запроса и вызова методов и свойств во время выполнения, а также варианты типов [9]: теговые объединения для представления полиморфных данных. (т.е. типы данных VB) и передача параметров в функции OLE IDispatch.

OLE был связующим звеном, необходимым для интеграции компонентов COM в среду выполнения Visual Basic, поэтому он напрямую поддерживал типы данных Visual Basic, соглашения о вызовах и семантику, например индексированные свойства.

OLE также предоставил язык определения интерфейса (ILD), который вы могли бы скомпилировать в двоичные библиотеки типов, использовать для генерации шаблонных интерфейсов C и C ++, а OLE также имел COM-интерфейсы и структуры для предоставления этих библиотек типов во время выполнения. Он также имел много постоянства, отражения во время выполнения и пользовательского интерфейса для подключения компонентов и диалогов в окнах, предоставления таблиц свойств, редактирования и настройки элементов управления и т. Д.

MIDL поддерживал определение компонентов с помощью «двойных интерфейсов» [10]: как интерфейсов OLE IDispatch, принимающих параметры типа варианта, так и более эффективного низкоуровневого интерфейса COM, принимающего примитивные типы. Такие среды выполнения, как Visual Basic, знали, как интегрировать двойные интерфейсы и могли связываться с более эффективными базовыми интерфейсами COM, вместо того чтобы проходить через более медленные универсальные динамические интерфейсы IDispatch.

IDL также описал тонкости интерфейсов DCOM [11] (для внутрипроцессных и сетевых удаленных вызовов процедур), маршаллинга параметров [12] и всех других странных вещей. DCOM - это то, где COM ушёл в глубокий конец.

По сути, COM был по сути очень простой и оригинальной идеей, которая элегантно решала некоторые проблемы реального мира, но в конечном итоге превратилась в нечто чрезвычайно сложное, которое пыталось решить многие другие не связанные с этим проблемы, и которое требовало огромного количества инструментов, и это зависело от в среде Microsoft Visual Studio и Win32.

Microsoft фактически портировала ActiveX на Mac

Глава 2. Клиент - Серверная модель COM

В главе 1 упоминалось, как COM поддерживает модель взаимодействия клиент / сервер между пользователем сервисов объекта, клиентом и разработчиком этого объекта и его сервисами, сервером. Точнее говоря, клиент - это любой фрагмент кода (не обязательно приложение), который каким-то образом получает указатель, через который он может получить доступ к службам объекта, а затем при необходимости вызывает эти службы. Сервер представляет собой некоторый фрагмент кода, который реализует объект и структуры таким образом, что библиотека COM может сопоставить эту реализацию с идентификатором класса или CLSID. Участие идентификатора класса - это то, что отличает сервер от более общего разработчика объектов.

Библиотека COM использует CLSID для предоставления клиентам услуг «определения местоположения». Клиенту нужно только сообщить COM CLSID, который он хочет, и тип сервера - внутрипроцессного, локального или удаленного - что он позволяет COM загружать или запускать. COM, в свою очередь, находит реализацию этого класса и устанавливает связь между ним и клиентом. Эта связь между клиентом, COM и сервером показана на рисунке 2-2 на следующей странице.

В главе 1 также была представлена ​​идея прозрачности расположения, когда клиентам и серверам никогда не нужно знать, насколько далеко они на самом деле находятся, то есть находятся ли они в одном процессе, в разных процессах или на разных машинах.

В этом разделе теперь подробнее рассматриваются механизмы COM, которые обеспечивают эту прозрачность, а также обязанности клиентских и серверных приложений.

Рисунок 2-2: Клиенты обнаруживают и получают доступ к объектам через сервисы определения местоположения в COM COM затем соединяет клиента с объектом на сервере. Сравните это с рисунком 1-2 в главе 1.

COM-объекты и идентификаторы классов

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

COM-объект - это объект, который идентифицируется уникальным 128-битным CLSID, который связывает класс объекта с определенной DLL или EXE в файловой системе. CLSID сам по себе является GUID (например, идентификатором интерфейса), поэтому никакой другой класс, независимо от того, какой поставщик его пишет, не имеет дублированного CLSID. Разработчики серверов обычно получают идентификаторы CLSID через функцию CoCreateGUID в COM или с помощью инструмента с поддержкой COM, который вызывает эту функцию изнутри.

Использование уникальных идентификаторов CLSID исключает возможность конфликтов имен между классами, поскольку идентификаторы CLSID никоим образом не связаны с именами, используемыми в базовой реализации. Так, например, два разных поставщика могут писать классы, которые они называют «StackClass», но каждый из них будет иметь уникальный CLSID и, следовательно, избегать любой возможности коллизии.

Кроме того, не требуется никакого центрального авторитетного и бюрократического органа для распределения или назначения идентификаторов CLSID. Таким образом, разработчики серверов по всему миру могут самостоятельно разрабатывать и развертывать свое программное обеспечение, не опасаясь случайного столкновения с программным обеспечением, написанным другими.

В своей хост-системе COM поддерживает базу данных регистрации (или «реестр») всех идентификаторов CLSID для серверов, установленных в системе, то есть сопоставление между каждым идентификатором CLSID и расположением библиотеки DLL или EXE, в которой находится сервер для этого. CLSID. COM обращается к этой базе данных всякий раз, когда клиент хочет создать экземпляр класса COM и использовать его сервисы. Этот клиент, однако, должен знать только CLSID, который не зависит от конкретного расположения DLL или EXE на конкретной машине.

Если запрошенный CLSID не найден в локальной базе данных регистрации, доступны различные другие административно-управляемые алгоритмы, с помощью которых можно попытаться найти реализацию в сети, к которой может быть подключен локальный компьютер; это объясняется более подробно ниже.

Учитывая CLSID, COM вызывает часть себя, называемую диспетчером управления службами (SCM [конечно, в разговорной речи произносится «scum»]), который является системным элементом, который находит код для этого CLSID. Код может существовать в виде DLL или EXE на том же компьютере или на другом компьютере: SCM изолирует большую часть COM, а также всех приложений от конкретных действий, необходимых для обнаружения кода. Мы вернемся к обсуждению SCM через минуту после изучения ролей клиентских и серверных приложений.

COM клиенты

Независимо от того, какое приложение передает CLSID в COM и запрашивает возвращенный экземпляр объекта, это COM-клиент. Конечно, так как этот клиент использует COM, это также приложение COM, которое должно выполнить необходимые шаги, описанные выше и в последующих главах.

Независимо от типа используемого сервера (внутрипроцессный, локальный или удаленный), COM-клиент всегда просит COM создавать экземпляры объектов одним и тем же способом. Простейший метод создания одного объекта - это вызов COM-функции CoCreateInstance. Это создает один объект с указанным CLSID и возвращает указатель интерфейса любого типа, который запрашивает клиент. Альтернативно, клиент может получить указатель интерфейса на то, что называется объектом «фабрики классов» для CLSID, вызвав CoGetClassObject. Эта фабрика классов поддерживает интерфейс под названием IClassFactory, через который клиент запрашивает у этой фабрики объект своего класса. На этом этапе у клиента есть указатели интерфейса для двух отдельных объектов, фабрики классов и объекта этого класса, каждый из которых имеет свой собственный счетчик ссылок. Это важное различие, которое проиллюстрировано на рисунке 2-3 и пояснено далее в главе 5.

Рисунок 2-3: COM-клиент создает объекты через фабрику классов.

Функция CoCreateInstance внутренне вызывает сам CoGetClassObject. Это просто более удобная функция для клиентов, которые хотят создать один объект.

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

COM-серверы

Существует два основных типа объектных серверов:

На основе библиотеки динамических ссылок (DLL): сервер реализован в модуле, который можно загрузить в адресное пространство клиента и выполнять в нем. (Термин DLL используется в данной спецификации для описания любого механизма разделяемой библиотеки, который присутствует на данной платформе COM.)

На основе EXE: сервер реализован в виде отдельного исполняемого модуля.

Поскольку COM допускает распределенные объекты, он также позволяет реализовать два основных типа серверов на удаленной машине. Чтобы разрешить клиентским приложениям активировать удаленные объекты, COM определяет диспетчер управления службами (SCM), роль которого описана ниже в разделе «Библиотека COM».

Поскольку клиент отвечает за использование фабрики классов и за управление сервером, сервер отвечает за реализацию фабрики классов, реализацию класса объектов, производимых фабрикой, выставление фабрики классов на COM и обеспечение выгрузки сервера под правильные условия. Диаграмма, иллюстрирующая, что существует внутри серверного модуля (EXE или DLL), показана на рисунке 2-4.

Рисунок 2-4: Общая структура COM-сервера.

То, как сервер выполняет эти требования, зависит от того, реализован ли сервер в виде DLL или EXE, но не зависит от того, находится ли сервер на том же компьютере, что и клиент, или на удаленном компьютере. Таким образом, удаленные серверы такие же, как локальные серверы, но они были зарегистрированы, чтобы быть видимыми для удаленных клиентов. В главе 6 рассматриваются все необходимые подробности об этих реализациях, а также о том, как сервер публикует свое существование в COM в регистрационной базе данных.

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

Глава 3. COM технология во встраиваемых системах

По большей части, компонентные технологии выросли из промышленности, а не из научных кругов, и развивались в нескольких направлениях. В области предприятия распределенная вычислительная среда (DCE) Open Group была разработана в начале 1990-х годов и обеспечивала инфраструктуру для создания распределенных приложений. Это было первое решение, которое использовало формализованный язык описания интерфейса. IDL-диалект DCE использовался для автоматической генерации прокси на стороне клиента и на стороне сервера, скрывая низкоуровневое оборудование, используемое для межпроцессного и межмашинного взаимодействия, и, таким образом, значительно упрощая реализацию распределенных вычислений (Open Software Foundation 1995; Hludzinski 1998). DCE предоставляется только для удаленных вызовов процедур без семантики объекта. Это было исправлено с помощью общей архитектуры брокера запросов объектов (OMBA CORBA), которая помогла гетерогенным объектно-ориентированным системам взаимодействовать.

Усилия Microsoft начались на настольных компьютерах и стали результатом усилий, направленных на то, чтобы повысить эффективность взаимодействия ее офисных приложений. Технология, получившая название Object Linking and Embedding (OLE), позволяла документам, созданным в одном приложении, связывать или встраивать документы, созданные в других приложениях. OLE позволила, скажем, слайду презентации содержать встроенную электронную таблицу, которую можно редактировать «на месте», дважды щелкнув по ней (не выходя из программного обеспечения для презентации). Результатом технологии компонентов стала объектная модель компонентов (COM), более поздние воплощения которой конкурировали с CORBA в корпоративном пространстве. Другие организации также разработали технологию объединения различных видов носителей в одном документе (такие документы известны как составные документы). Apple основывала свою (ныне упраздненную) конкурирующую технологию OpenDoc на Системной объектной модели International Business Machines (SOM IBM) (Alger 1994).

Снова на настольном компьютере Microsoft получила ранний успех с Visual Basic и ее поддержкой стороннего программного обеспечения, доступной как «пользовательские элементы управления». Позже Visual Basic основывал свою компонентную технологию на COM. Delphi-продукт Borland был совместим с компонентами, созданными для Visual Basic, но также имел собственные объектные и компонентные модели и полностью скомпилированный язык со строгой типизацией.

Многие из наиболее популярных современных моделей компонентов для настольных компьютеров и предприятий построены на платформах, основанных на функциональных виртуальных машинах, что значительно упрощает технологию компонентов. Java-технология Sun, а также преемник Microsoft .NET относятся к этой категории.

Компонентная объектная модель (COM) возникла в результате усилий Microsoft, направленных на совместную работу различных частей ее пакета производительности Office. Первая версия технологии связывания и вложения объектов (OLE) позволяла одному приложению, такому как Microsoft Word, встраивать содержимое другого, например Microsoft Excel, таким образом реализовывая составные документы. Во второй версии OLE добавлены такие вещи, как редактирование на месте и перетаскивание. В то время как OLE 1.0 была автономной технологией, Microsoft решила отделить объектную и компонентную модели от OLE при создании OLE 2.0, поскольку поняла, что технология, созданная для OLE, может быть полезна и в других контекстах. Тони Уильямс, один из архитекторов COM в Microsoft, говорит об этом так: «Мы решили укусить пулю и сделать гораздо более формализованную модель того, что является объектом, что значит иметь интерфейсы, что значит вести переговоры над ними - и [...] которые стали COM »(Microsoft 2006). Хотя COM и OLE были созданы одной и той же командой, Microsoft сохранила четкое различие между ними. OLE 2.0 был многоуровневым поверх COM и состоял из большого количества интерфейсов и небольшой системы времени выполнения.

С тех пор COM значительно изменился. Система времени выполнения COM поставляется со всеми современными версиями Windows, а доступ к большому количеству служб Windows осуществляется через интерфейсы COM. COM также зарекомендовал себя как средство реализации компонентных технологий для сторонних разработчиков. Богатая экосистема, которая выросла вокруг компонентов ActiveX, основанных на COM, является тому примером (Szyperski et al. 2002: 26). COM может использоваться для реализации распределенных вычислений с помощью Distributed COM (DCOM) и корпоративных сервисов (таких как перечисленные в разделе 1.7) через COM + (Bukovics 2006).

COM оказал глубокое влияние на отрасль. Хотя исходная система времени выполнения поддерживает большое количество приложений и сервисов на платформе Windows, именно идеи, лежащие в основе COM, оказали наибольшее влияние. Многие компонентные модели являются более или менее точными копиями COM. Несмотря на Windows-ориентированную природу COM 1, технология широко доступна на других платформах, и ее поставщики, кроме Microsoft, реализуют ее заново. Продукты Mozilla, такие как веб-браузер Firefox, используют COM-совместимую технологию, известную как XPCOM («XP» означает «кроссплатформенный») (Turner and Oeschger 2003). Компонентная модель UNO для включения OLE-подобных функций, таких как встраивание, активация на месте и создание сценариев с использованием языка BASIC (Sun Microsystems 2007).

Во встроенной области многие модели компонентов находятся под сильным влиянием COM. Универсальный домашний API (UHAPI) от Philips и Samsung для бытовой электроники сильно заимствует у COM с его технологией uhCOM. Операционная система Symbian для мобильных телефонов использует COM-модель под названием ECom (Symbian Foundation 2008). АББ использует COM-подобную технологию для своих программируемых контроллеров, чтобы увеличить модульность своей кодовой базы (Lüders et al. 2005).

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

С помощью своего двоичного стандарта COM стандартизирует механизм доступа к объектам, предписывая конкретную схему памяти, соглашение о вызовах и систему типов. Поскольку интерфейсы являются единственным средством доступа к COM-объектам, COM считается двоичным стандартом для интерфейсов. Компоновка памяти, предписанная COM, особенно совместима с чисто виртуальными классами C ++, созданными собственным компилятором C ++ от Microsoft. В результате COM идет по пути стандартизации двоичного интерфейса приложения C ++ (ABI) на платформе Windows, что позволяет создавать код другими совместимыми компиляторами C ++, по крайней мере, в том, что касается COM2. Поставщики компиляторов для языков, отличных от C ++, должны также придерживаться стандарта, если их язык должен быть совместим с COM. Интегрированная среда разработки Embarcadero Delphi, чей язык программирования Delphi является разновидностью Object Pascal, полностью соответствует двоичному стандарту COM, создавая COM-совместимые объекты (Calvert 1999: 381). Таким образом, COM успешно создает стандарт, который позволяет разнородным объектно-ориентированным языкам взаимодействовать без потери их семантики объекта, и делает это только путем стандартизации абсолютного минимума, необходимого для обеспечения двоичной совместимости.

Схема памяти COM-интерфейсов

Двоичный стандарт COM аналогичен, но не идентичен, двоичному стандарту, разработанному в главе 4. Как и этот двоичный стандарт, COM не поддерживает наследование реализации, которое можно рассматривать как функцию (как описано в разделе 4.3.2). Клиентская переменная указывает на область памяти, первый элемент которой указывает на таблицу диспетчеризации, поля которой указывают на фактическую реализацию (Szyperski et al. 2002: 330). Рисунок 5.1 показывает это визуально. Первым аргументом функции, которая служит реализацией операции COM, должен быть указатель this, что опять же согласуется с главой 4. Это позволяет COM демонстрировать истинные характеристики объекта.

Класс COM может реализовывать любое количество интерфейсов. Все интерфейсы напрямую происходят от одного другого интерфейса, кроме IUnknown, корня иерархии наследования интерфейса (по соглашению, все имена интерфейсов во время компиляции начинаются с «I»). IUnknown для большинства намерений и целей идентичен интерфейсу Fundamental, представленному в главе 4. COM-эквивалентом операции Fundamental :: SwitchInterface () являются IUnknown :: QueryInterface (), а также Fundamental :: AddReference () и Fundamental :: RemoveReference () соответствуют IUnknown :: AddRef () и IUnknown :: Release () соответственно.

COM использует подсчет ссылок для управления памятью. Объекты не должны быть подсчитаны по всей их полноте - каждый интерфейс, реализованный объектом, может быть подсчитан по отдельности. Эта функция известна как отрывные интерфейсы и может использоваться объектом для инициализации и уничтожения ресурсов для каждого интерфейса, что позволяет экономить ресурсы (Szyperski et al. 2002: 334).

Имена времени выполнения должны быть назначены большому количеству различных объектов COM, включая классы и интерфейсы. Для этой цели COM использует универсальные уникальные идентификаторы (UUID), также называемые глобальными уникальными идентификаторами (GUID). UUID - это 128-битное число, которое имеет очень высокую вероятность быть глобально уникальным. Текстовое представление UUID может выглядеть следующим образом: «7a3fc5d3-f79a-4de5-827d-d0f5619a4c99». Реестр Windows служит хранилищем данных, которое отображает UUID в компоненты (общие библиотеки для объектов, которые выполняются в процессе, и исполняемые файлы для объектов, которые выполняются вне процесса). (Последние версии Windows поддерживают внутрипроцессные COM-компоненты, которые не доступны глобально, и, следовательно, их не нужно хранить в реестре (Templin 2005).)

Ожидается, что операции в интерфейсах COM предоставят информацию об ошибке в виде целочисленных возвращаемых значений, известных как HRESULT. Истинные возвращаемые значения предоставляются в качестве выходных аргументов. Значение HRESULT - это 32-разрядное целочисленное значение, разделенное на несколько полей.

В той мере, в которой COM поддерживает управление версиями, он делает это путем избегания. Интерфейсный UUID идентифицирует не только интерфейс, но и его версию, таким образом, требуя, чтобы интерфейсы после публикации никогда не менялись. Класс может легко поддерживать несколько версий интерфейса, реализуя все интерфейсы, соответствующие различным версиям. Более новые клиенты используют IUnknown :: QueryInterface () для запроса более новой версии, в то время как более старые клиенты запрашивают более старую версию.

COM-компонент может не только работать в контексте вызывающего, но также может запускаться в другом процессе или (через DCOM) на другом компьютере. Межпроцессное взаимодействие и межмашинное взаимодействие облегчаются с помощью прокси на стороне клиента и на стороне сервера, как объяснено в разделе 2.2.3 (в COM это называется «прокси» и «заглушки» соответственно). COM поддерживает синхронные (блокирующие) и асинхронные (неблокирующие) вызовы компонентов, работающих вне процесса (Prosise 2000a) .4

Маршаллинг может автоматически обрабатываться COM, называемый стандартным маршаллингом. Опытные пользователи, которые хотят самостоятельно обрабатывать все аспекты сортировки, могут использовать настраиваемую сортировку. Последнее может быть предпочтительным для приложений, критичных к производительности, поскольку оно позволяет обрабатывать определенные операции без отсылки к удаленному серверу, тем самым сокращая межпроцессные или межмашинные вызовы. Пользовательский прокси на стороне клиента может, например, кэшировать данные в клиентском процессе и прозрачно работать в этом состоянии вместо обращения к удаленному объекту. Многие из преимуществ пользовательского маршаллинга могут быть получены с использованием внутрипроцессных обработчиков, без сложности предыдущего подхода. Внутрипроцессный обработчик может выбрать обработку некоторых операций локально, в то же время делегируя другие операции стандартному распределению (Prosise 2000b).

COM может использоваться с языком описания интерфейса COM IDL, но в качестве бинарного стандарта использование этого языка, строго говоря, необязательно. COM IDL - это расширенная версия IDL DCE, в частности добавление объектов к языку (Hludzinski 1998). Компилятор Microsoft IDL может генерировать прокси на стороне клиента и на стороне сервера, привязки к языку C / C ++, а также библиотеки типов. Библиотека типов - это нетекстовое, эффективное представление набора файлов IDL, которые могут быть развернуты в системах конечных пользователей в виде автономных файлов или встроены в качестве ресурсов в общие библиотеки или исполняемые файлы. по существу, хранилище информации о типах, доступной во время выполнения. Система времени выполнения COM может читать библиотеки типов и делать доступными в них данные через интерфейс ITypeInfo. Привязки к языкам обычно создаются не непосредственно из файлов IDL, а из библиотек типов, поскольку библиотеки типов - это объекты, которые развертываются в системах конечных пользователей.

Фабрики используются в COM для создания экземпляров классов. Для того чтобы класс был инстанцируемым, должна существовать реализация IClassFactory, которая может создавать экземпляр указанного класса. Компонент COM, который выполняется в процессе (и, следовательно, реализуется как разделяемая библиотека), должен экспортировать функцию, которая возвращает объект, реализующий IClassFactory для данного класса UUID, переданного в качестве аргумента. Компонент COM, который выполняется вне процесса на том же компьютере, реализован в виде стандартного исполняемого файла, который при запуске регистрирует свою фабрику классов в системе времени выполнения COM (Goswell 1995).

Одним из преимуществ COM является то, что он позволяет то, что Microsoft называет автоматизацией, - возможность для одной программы, обычно сценария, получать доступ к другой программе и управлять ею, что часто пишется в собственном коде. Сценарий, написанный на Visual Basic, может, например, использовать механизм построения диаграмм Microsoft Excel через Automation. Автоматизация позволяет приложениям предоставлять доступ к своим функциям в виде набора объектов COM.

Автоматизация подразумевает, что достоверность вызовов проверяется только во время выполнения, поэтому используется очень позднее связывание (см. Раздел 4.2). Традиционное решение в COM состоит в том, чтобы требовать, чтобы классы, которые хотят быть доступными через очень позднее связывание, реализовали интерфейс IDispatch, который аналогичен интерфейсу Scriptable, представленному в главе 4. (Классы, доступные как с поздним связыванием, так и с очень поздним связыванием, и таким образом реализовать IDispatch в дополнение к традиционным, специфичным для домена интерфейсам, которые, как говорят, используют двойные интерфейсы). IDispatch :: Invoke (), в отличие от Scriptable :: InvokeOperation (), не принимает строку, представляющую имя операции в качестве аргумента. Скорее, он принимает идентификатор отправки, который может быть получен во время выполнения с использованием IDispatch :: GetIDsOfNames (), предположительно из соображений эффективности. Если компонент поставляется с библиотекой типов, реализация интерфейса IDispatch может быть полностью синтезирована во время выполнения или просто путем переадресации вызовов в предоставляемую системой реализацию ITypeInfo.

Если компилятор создает классы, несовместимые с бинарным стандартом COM, эти классы нельзя использовать в качестве средств прямой реализации классов COM. Тем не менее, COM полностью доступен для любой программы, скомпилированной с собственным кодом, которая дает прямой доступ к памяти, такой как программы, написанные на C. Класс COM, написанный на C, не выглядит так уж сильно отличается от классов, представленных в Главе 4.

Бинарная совместимость с C ++ гораздо больше, чем доступ к объектам, созданным из чисто виртуальных классов. Это включает обработку исключений, информацию о типах среды выполнения, искажение имен и (возможно, множественное) наследование реализации (Clamage 2002). COM обходит многие из этих проблем - вместо исключений используются возвращаемые значения, наследование реализации не поддерживается, и искажение имен выше стандартизированного C не требуется, так как двоичный стандарт COM основан на таблицах диспетчеризации. Кроме того, COM предоставляет свои собственные стандарты для информации о типах во время выполнения в форме IUnknown :: QueryInterface () и библиотек типов.

На 32-разрядных компьютерах COM использует соглашение о вызовах stdcall вместо соглашения о вызовах thiscall, обычно используемого компилятором Microsoft C ++. Последнее соглашение о вызовах передает указатель this через регистр, а не в стек вызовов, тогда как stdcall передает все аргументы в стеке. C может легко поддерживать COM, так как большинство реализаций C для Windows поддерживают соглашение о вызовах stdcall. Поскольку вызываемый отвечает за очистку стека при использовании stdcall, это соглашение о вызовах (и, следовательно, COM) не может поддерживать переменные аргументы (операции, которые принимают определенное вызывающим абонентом количество аргументов).

Для выполнения межмашинных вызовов DCOM использует объектно-ориентированный вариант проводного формата DCE для удаленных вызовов процедур, который называется Object RPC (Eddon and Eddon 1998). DCOM связывается со службой, известной как диспетчер управления службами на удаленном компьютере, для обработки и маршрутизации вызовов между компьютерами. Эта служба выполняет функцию, аналогичную ORB в CORBA, которая обсуждается в разделе 5.4 (Szyperski et al. 2002: 341).

Библиотеки типов могут представлять только подмножество информации, содержащейся в файлах IDL. Например, библиотека типов не может представлять несколько выходных аргументов (Hunt and Scott 1999).

Заключение

Технологи COM оставила свою пусть и противоречивую, но объемную значимую в истории. Как видно из содержания курса распространение технологии (встраиваемые системы) и ее эволюция (COBRA) показало, что индустрия заинтересована в решениях основанных на переиспользуемых компонентах. Особенно критично это до времен всеобщей миниатюризации, когда аппаратная составляющая еще не была настолько относительно доступной, что заставляло задумываться над рациональным расходом материальных ресурсов машин. Было довольно много попыток возродить / видоизменить технологию взять тот же SOM или, один из самых популярных на сегодняшний день WebComponents, WASM - по сути является новой реинкарнацией классической модели. Приживется ли она в этот раз? Покажет время.

Библиография

[1] Virtual Method Table: https://en.wikipedia.org/wiki/Virtual_method_table

[2] VBX: https://en.wikipedia.org/wiki/Visual_Basic_Extension

[3] Variant Type: https://en.wikipedia.org/wiki/Variant_type

[4] IUnknown::QueryInterface: https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...

[5] dynamic_cast: https://msdn.microsoft.com/en-us/library/windows/desktop/ff4...

[6] Aggregation: https://msdn.microsoft.com/en-us/library/windows/desktop/ms6...

[7] Tear Off Interface: http://www.codeguru.com/cpp/com-tech/atl/performance/article...

[8] ActiveX Template Library: http://www.drdobbs.com/windows/the-activex-template-library/...

[9] Variant Types: https://en.wikipedia.org/wiki/Variant_type

[11] Distributed COM: https://en.wikipedia.org/wiki/Distributed_Component_Object_M...

[12] Marshalling: https://en.wikipedia.org/wiki/Marshalling_(computer_science)

[13] Macromedia Open Architecture (MOA): https://www.adobe.com/support/xtras/info/moa.html

[14] XP/COM: https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM

[15] deCOMtamination: https://wiki.mozilla.org/Gecko:DeCOMtamination http://taras.glek.net/blog/categories/decomtamination/ https://blog.mozilla.org/tglek/category/decomtamination/

Приложение