Компонентная объектная модель - Component Object Model

COM
Компонентная объектная модель
Положение дел Действующий
Впервые опубликовано 1993 ; 28 лет назад ( 1993 )
Последняя версия Уровень жизни
2021 г.
Организация Microsoft
Серии Системные услуги
Базовые стандарты MIDL , UUID
Связанные стандарты
Домен Компонент Интерфейс
Сокращенное название COM
Веб-сайт документы .microsoft .com / en-us / windows / win32 / com / компонент-объект-модель

Component Object Model ( COM ) - это стандарт двоичного интерфейса для программных компонентов, представленный Microsoft в 1993 году. Он используется для создания объектов межпроцессного взаимодействия в большом диапазоне языков программирования . COM является основой для нескольких других технологий и сред Microsoft, включая OLE , OLE Automation , объект поддержки браузера , ActiveX , COM + , DCOM , оболочку Windows , DirectX , UMDF и среду выполнения Windows . Суть COM - это не зависящий от языка способ реализации объектов, которые можно использовать в средах, отличных от той, в которой они были созданы, даже за пределами машин. Для хорошо написанных компонентов COM позволяет повторно использовать объекты, не зная об их внутренней реализации, поскольку заставляет разработчиков компонентов предоставлять четко определенные интерфейсы , которые отделены от реализации. Различная семантика распределения языков учитывается путем возложения на объекты ответственности за их собственное создание и уничтожение посредством подсчета ссылок . Преобразование типов между различными интерфейсами объекта достигается с помощью этого метода. Предпочтительный метод «наследования» в COM - это создание подобъектов, которым делегируются «вызовы» методов. QueryInterface

COM - это интерфейсная технология, определенная и реализованная в качестве стандарта только в Microsoft Windows и Apple Core Foundation 1.3 и более поздних версиях программного интерфейса (API) подключаемых модулей . Последний реализует только подмножество всего COM-интерфейса. Для некоторых приложений COM был по крайней мере частично заменен платформой Microsoft .NET и поддержкой веб-служб через Windows Communication Foundation (WCF). Однако COM-объекты можно использовать со всеми языками .NET через .NET COM Interop . Сетевой DCOM использует проприетарные двоичные форматы , в то время как WCF поощряет использование обмена сообщениями SOAP на основе XML . COM очень похож на другие технологии интерфейса компонентного программного обеспечения , такие как CORBA и Enterprise JavaBeans , хотя у каждой есть свои сильные и слабые стороны. В отличие от C ++, COM предоставляет стабильный двоичный интерфейс приложения (ABI), который не меняется между выпусками компилятора. Это делает COM-интерфейсы привлекательными для объектно-ориентированных библиотек C ++, которые должны использоваться клиентами, скомпилированными с использованием разных версий компилятора.

История

Одним из первых методов межпроцессного взаимодействия в Windows был динамический обмен данными (DDE), впервые представленный в 1987 году, который позволял отправлять и получать сообщения в так называемых «разговорах» между приложениями. Энтони Уильямс , который участвовал в создании архитектуры COM, позже распространил в Microsoft два внутренних документа, охватывающих концепцию программных компонентов: Объектная архитектура: работа с неизвестным или типом безопасности в динамически расширяемой библиотеке классов в 1988 году и О наследовании: что это означает и как его использовать в 1990 году. Они легли в основу многих идей, лежащих в основе COM. Связывание и внедрение объектов (OLE), первая объектно-ориентированная среда Microsoft, была построена на основе DDE и разработана специально для составных документов . Он был представлен в Word для Windows и Excel в 1991 году, а позже был включен в Windows, начиная с версии 3.1 в 1992 году. Примером составного документа является электронная таблица, встроенная в документ Word для Windows: по мере внесения изменений в электронную таблицу в Excel они автоматически появляются внутри документа Word.

В 1991 году Microsoft представила расширения Visual Basic (VBX) с Visual Basic 1.0. VBX - это упакованное расширение в виде библиотеки динамической компоновки (DLL), которая позволяет графически размещать объекты в форме и управлять ими с помощью свойств и методов . Позже они были адаптированы для использования другими языками, такими как Visual C ++ . В 1992 году, когда была выпущена версия Windows 3.1 , Microsoft выпустила OLE 2 с базовой объектной моделью . COM - двоичный интерфейс приложений (ABI) , был таким же , как MAPI ABI (выпущенный в 1992 году), и , как это было основано на MSRPC и в конечном счете на открытую группу «ы DCE / RPC . В то время как OLE 1 был ориентирован на составные документы, COM и OLE 2 были разработаны для работы с программными компонентами в целом. Текстовые разговоры и сообщения Windows оказались недостаточно гибкими, чтобы обеспечить надежный и расширяемый общий доступ к функциям приложений, поэтому COM был создан в качестве новой основы, а OLE сменили на OLE2. В 1994 году на смену элементам управления VBX были представлены пользовательские элементы управления OLE (OCX). В то же время Microsoft заявила, что OLE 2 будет называться просто «OLE», и что OLE больше не является аббревиатурой, а является названием для всех компонентных технологий компании. В начале 1996 года Microsoft нашла новое применение для настраиваемых элементов управления OLE, расширив возможности своего веб-браузера для представления содержимого, переименовав некоторые части OLE, относящиеся к Интернету, в « ActiveX » и постепенно переименовала все технологии OLE в ActiveX, за исключением технологии составных документов. который использовался в Microsoft Office . Позже в том же году Microsoft расширила COM для работы в сети с DCOM .

Связанные технологии

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

DDE

COM заменил DDE в качестве предпочтительной формы межпроцессного взаимодействия.

DCE / RPC и MSRPC

В качестве межъязыковой компонентной модели COM полагается на язык определения интерфейса, или IDL, для описания объектов и связанных функций. COM IDL в значительной степени основан на многофункциональном IDL DCE / RPC с объектно-ориентированными расширениями. Собственная реализация Microsoft DCE / RPC, известная как MSRPC, активно используется в качестве основного механизма межпроцессного взаимодействия для служб и внутренних компонентов Windows NT, что делает его очевидным выбором в качестве основы.

DCOM

DCOM ( Распределенный COM ) расширил возможности COM: от простой поддержки одного пользователя с отдельными приложениями, взаимодействующими на рабочем столе Windows, до активации объектов, работающих в разных контекстах безопасности и на разных машинах в сети. Вместе с этим были добавлены необходимые функции для настройки того, какие пользователи имеют право создавать, активировать и вызывать объекты, для идентификации вызывающего пользователя, а также указывать необходимое шифрование для безопасности вызовов.

COM +

Чтобы Microsoft могла предоставить разработчикам поддержку распределенных транзакций , пула ресурсов, отключенных приложений, публикации событий и подписки, лучшего управления памятью и процессором (потоками), а также позиционировать Windows как альтернативу другим операционным системам корпоративного уровня, Microsoft представила технологию под названием Microsoft Transaction Server (MTS) в Windows NT 4. В Windows 2000 это значительное расширение COM было включено в операционную систему (в отличие от серии внешних инструментов, предоставляемых MTS ) и переименовано в COM + . В то же время Microsoft перестала выделять DCOM как отдельную сущность. Компоненты, которые использовали службы COM +, обрабатывались более непосредственно добавленным уровнем COM +, в частности, за счет поддержки перехвата операционной системой. В первом выпуске MTS перехват был добавлен - установка компонента MTS изменяла реестр Windows для вызова программного обеспечения MTS, а не непосредственно компонента. Windows 2000 также доработала приложение панели управления службами компонентов, используемое для настройки компонентов COM +.

Преимущество COM + состояло в том, что его можно было запускать в «фермах компонентов». Экземпляры компонента при правильном кодировании могут быть объединены в пул и повторно использованы новыми вызовами его процедуры инициализации без выгрузки из памяти. Компоненты также могут быть распределены (вызваны с другой машины). COM + и Microsoft Visual Studio предоставили инструменты, упрощающие создание прокси на стороне клиента, поэтому, хотя DCOM использовался для удаленного вызова, это было легко сделать для разработчиков. COM + также представил механизм событий подписчика / издателя, называемый событиями COM + , и предоставил новый способ использования MSMQ (технологии, обеспечивающей асинхронный обмен сообщениями между приложениями) с компонентами, называемыми компонентами в очереди . События COM + расширяют модель программирования COM + для поддержки событий или вызовов методов с поздним связыванием (см. Раздел «Позднее связывание» ) между издателем или подписчиком и системой событий.

.СЕТЬ

Microsoft .NET предоставляет средства как для предоставления технологии компонентов, так и для взаимодействия с COM + (через сборки COM-взаимодействия); .NET предоставляет оболочки для большинства часто используемых элементов управления COM. Microsoft .NET скрывает большую часть деталей от создания компонентов и, следовательно, упрощает разработку. .NET может использовать COM + через пространство имен System.EnterpriseServices, а некоторые службы, предоставляемые COM +, были продублированы в последних выпусках .NET. Например, пространство имен System.Transactions в .NET предоставляет класс TransactionScope, который обеспечивает управление транзакциями без использования COM +. Точно так же компоненты в очереди могут быть заменены Windows Communication Foundation с транспортом MSMQ . (Однако MSMQ - это собственный компонент COM.) Имеется ограниченная поддержка обратной совместимости. COM-объект можно использовать в .NET, реализовав Runtime Callable Wrapper (RCW). Объекты .NET, которые соответствуют определенным ограничениям интерфейса, могут использоваться в объектах COM путем вызова вызываемой оболочки COM (CCW). Как со стороны COM, так и со стороны .NET объекты, использующие другую технологию, отображаются как собственные объекты. См. COM-взаимодействие . WCF (Windows Communication Foundation) упрощает ряд проблем удаленного выполнения COM. Например, он позволяет более легко упорядочивать объекты по значению через границы процесса или машины.

Среда выполнения Windows

Новая среда выполнения Microsoft Windows Runtime (или WinRT, не путать с Windows RT ), программирование и модель приложения, по сути, представляет собой API-интерфейс на основе COM, хотя и опирается на улучшенный COM. Благодаря своей основе, подобной COM, среда выполнения Windows позволяет относительно легко взаимодействовать с несколькими языками, как и COM, но по сути это неуправляемый собственный API. Однако определения API хранятся в файлах ".winmd", которые закодированы в формате метаданных ECMA 335, том же формате метаданных CLI , который использует .NET с некоторыми изменениями. Этот общий формат метаданных позволяет значительно снизить накладные расходы, чем P / Invoke, когда WinRT вызывается из приложений .NET, а его синтаксис намного проще.

Nano-COM (также известный как XPCOM)

Nano-COM - это чрезвычайно небольшое подмножество объектной модели компонентов, которое сосредоточено исключительно на аспектах двоичного интерфейса приложения (ABI) COM, чтобы разрешить вызовы функций и методов в независимо скомпилированных модулях / компонентах. Nano-COM можно легко выразить в одном файле заголовка C ++, который переносится на все компиляторы C ++. Nano-COM расширяет собственный ABI базовой архитектуры инструкций и ОС, добавляя поддержку для ссылок на типизированные объекты (типичные ABI сосредоточены только на атомарных типах, структурах, массивах и соглашениях о вызове функций). Основа Nano-COM использовалась Mozilla для начальной загрузки Firefox (называемого XPCOM ) и в настоящее время используется в качестве базовой технологии ABI для DirectX / Direct3D / DirectML .

Заголовочный файл Nano-COM определяет или называет как минимум три типа:

  • GUID для идентификации типов интерфейса - это фактически 128-битное число.
  • HRESULT для идентификации кодов ошибок из вызовов методов - это фактически стандартизованное использование 32-битных целых чисел для хорошо известных значений (S_OK, E_FAIL, E_OUTOFMEMORY и т. Д.)
  • I Не известен как базовый тип для всех ссылок на типизированные объекты - это фактически абстрактные виртуальные функции для поддержки dynamic_cast<T>получения новых типов интерфейсов в стиле и подсчета ссылок a lashared_ptr<T>

Многие применения Nano-COM также определяют две функции для адресации буферов памяти, выделенных вызываемым пользователем, в качестве результатов.

  • <NanoCom> Alloc - вызывается реализациями метода для выделения необработанных буферов (не объектов), которые возвращаются вызывающей стороне
  • <NanoCom> Free - вызывается вызывающими методами для освобождения буферов, выделенных вызываемым пользователем, когда они больше не используются

Некоторые реализации Nano-COM, такие как Direct3D, избегают функций распределителя и ограничивают себя только использованием буферов, выделенных вызывающим абонентом.

Nano-COM не имеет понятия о классах, квартирах, маршалинге, регистрации и т. Д. Скорее, ссылки на объекты просто передаются через границы функций и выделяются с помощью стандартных языковых конструкций (например, оператора new C ++).

Безопасность

Компоненты COM и ActiveX запускаются как собственный код на компьютере пользователя без изолированной программной среды. Поэтому есть несколько ограничений на то, что может делать код. Таким образом, предыдущая практика встраивания компонентов ActiveX на веб-страницы с помощью Internet Explorer приводила к проблемам с заражением вредоносными программами . Microsoft осознала проблему ActiveX еще в 1996 году, когда Чарльз Фицджеральд сказал: «Мы никогда не заявляли заранее, что ActiveX по своей сути безопасен». Последние версии Internet Explorer запрашивают пользователя перед установкой элементов управления ActiveX, что позволяет пользователю запретить установку элементов управления с сайтов, которым он не доверяет. Элементы управления ActiveX будут подписаны с цифровыми подписями , чтобы гарантировать их подлинность. Также можно полностью отключить элементы управления ActiveX или разрешить только некоторые из них. Прозрачная поддержка внепроцессных COM-серверов по-прежнему способствует безопасности программного обеспечения с точки зрения изоляции процессов . Это может быть полезно для разделения подсистем большого приложения на отдельные процессы. Изоляция процесса ограничивает повреждение состояния в одном процессе от негативного воздействия на целостность других процессов, поскольку они взаимодействуют только через строго определенные интерфейсы. Таким образом, для восстановления допустимого состояния необходимо перезапустить только затронутую подсистему. Это не относится к подсистемам в одном процессе, где мошеннический указатель в одной подсистеме может случайным образом повредить другие подсистемы.

Технические подробности

Программисты COM создают свое программное обеспечение, используя компоненты, поддерживающие COM . Различные типы компонентов идентифицируются идентификаторами класса (CLSID), которые являются глобальными уникальными идентификаторами (GUID). Каждый компонент COM предоставляет свои функции через один или несколько интерфейсов . Различные интерфейсы, поддерживаемые компонентом, отличаются друг от друга с помощью идентификаторов интерфейсов (IID), которые также являются идентификаторами GUID. COM-интерфейсы имеют привязки к нескольким языкам, таким как C , C ++ , Visual Basic , Delphi , Python и нескольким языкам сценариев, реализованным на платформе Windows. Весь доступ к компонентам осуществляется через методы интерфейсов. Это позволяет использовать такие методы, как межпроцессное или даже межкомпьютерное программирование (последнее с использованием поддержки DCOM).

Интерфейсы

Все компоненты COM реализуют интерфейс IUnknown ( настраиваемый ), который предоставляет методы для подсчета ссылок и преобразования типов (приведения). Пользовательский интерфейс IUnknown состоит из указателя на виртуальную таблицу метод , который содержит список указателей на функции , которые реализуют функции , объявленные в интерфейсе, в том же порядке , что они были объявлены в интерфейсе. Таким образом, накладные расходы на вызовы внутри процесса сопоставимы с вызовами виртуальных методов в C ++ . В дополнение к настраиваемым интерфейсам COM также поддерживает интерфейсы диспетчеризации, унаследованные от IDispatch . Интерфейсы диспетчеризации поддерживают позднее связывание для OLE Automation . Это позволяет осуществлять доступ к интерфейсам диспетчеризации из более широкого диапазона языков программирования, чем пользовательские интерфейсы.

Классы

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

Язык определения интерфейса и библиотеки типов

Библиотеки типов содержат метаданные для представления типов COM. Эти типы описаны с помощью языка определения интерфейса Microsoft (MSIDL / IDL). Файлы IDL определяют объектно-ориентированные классы, интерфейсы, структуры, перечисления и другие определяемые пользователем типы независимо от языка. IDL по внешнему виду похож на объявления C ++ с некоторыми дополнительными ключевыми словами, такими как «интерфейс» и «библиотека» для определения интерфейсов и коллекций классов. IDL также поддерживает использование атрибутов в квадратных скобках перед объявлениями для предоставления дополнительной информации, такой как идентификаторы GUID интерфейса и отношения между параметрами указателя и полями длины. Файлы IDL компилируются компилятором MIDL . Для C / C ++ компилятор MIDL генерирует независимый от компилятора файл заголовка, содержащий определения структур, соответствующие vtbls объявленных интерфейсов, и файл C, содержащий объявления GUID интерфейсов . Исходный код C ++ для прокси-модуля также может быть сгенерирован компилятором MIDL. Этот прокси-сервер содержит заглушки методов для преобразования вызовов COM в вызовы удаленных процедур, чтобы включить DCOM для взаимодействия вне процесса. Файлы IDL также могут быть скомпилированы компилятором MIDL в библиотеку типов (TLB). Файлы TLB содержат двоичные метаданные, которые могут обрабатываться компиляторами разных языков и средами выполнения (например, VB, Delphi, .NET и т. Д.) Для создания языковых конструкций для представления типов COM, определенных в TLB. Для C ++ это преобразует TLB обратно в его представление IDL.

Фреймворк объекта

Поскольку COM - это среда выполнения, типы должны быть индивидуально идентифицируемыми и определяемыми во время выполнения. Для этого используются глобальные уникальные идентификаторы (GUID). Каждому типу COM назначается собственный идентификатор GUID для идентификации во время выполнения. Чтобы информация о типах COM была доступна как во время компиляции, так и во время выполнения, COM использует библиотеки типов. Благодаря эффективному использованию библиотек типов COM реализует свои возможности в качестве динамической структуры для взаимодействия объектов.

Рассмотрим следующий пример определения кокласса в IDL:

coclass SomeClass {
  [default] interface ISomeInterface;
};

В приведенном выше фрагменте кода объявляется COM-класс с именем, SomeClassкоторый реализует интерфейс с именем ISomeInterface.

Это концептуально эквивалентно определению следующего класса C ++:

class SomeClass : public ISomeInterface {
  ...
  ...
};

где ISomeInterface - это чистый виртуальный класс C ++ (иногда называемый абстрактным базовым классом).

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

В C ++ объекты COM создаются с помощью CoCreateInstanceфункции, которая принимает в качестве аргументов идентификатор класса (CLSID) и идентификатор интерфейса (IID). Создание экземпляра SomeClassможет быть реализовано следующим образом:

ISomeInterface* interface_ptr = NULL;
HRESULT hr = CoCreateInstance(CLSID_SomeClass, NULL, CLSCTX_ALL,
                              IID_ISomeInterface, (void**)&interface_ptr);

В этом примере подсистема COM используется для получения указателя на объект, реализующий ISomeInterfaceинтерфейс, и требуется конкретная реализация этого интерфейса CLSID_SomeClass.

Подсчет ссылок

Все COM-объекты используют подсчет ссылок для управления временем жизни объекта. Счетчики ссылок контролируются клиентами с помощью методов AddRef и Release в обязательном интерфейсе IUnknown, который реализуют все COM-объекты. Затем COM-объекты отвечают за освобождение собственной памяти, когда счетчик ссылок падает до нуля. Некоторые языки (например, Visual Basic ) обеспечивают автоматический подсчет ссылок, поэтому разработчикам COM-объектов не нужно явно поддерживать какой-либо внутренний счетчик ссылок в своих исходных кодах. В C ++ кодировщик может либо выполнять явный подсчет ссылок, либо использовать интеллектуальные указатели для автоматического управления счетчиком ссылок.

Ниже приведены рекомендации о том, когда вызывать AddRef и Release для COM-объектов:

  • Функции и методы, возвращающие ссылки на интерфейс (через возвращаемое значение или через параметр "out"), должны увеличивать счетчик ссылок возвращаемого объекта перед возвратом.
  • Release должен быть вызван для указателя интерфейса до того, как указатель будет перезаписан или выйдет за пределы области видимости.
  • Если копия сделана для указателя ссылки на интерфейс, для этого указателя следует вызвать AddRef .
  • AddRef и Release должны вызываться для конкретного интерфейса, на который ссылаются, поскольку объект может реализовывать счетчики ссылок для каждого интерфейса, чтобы выделять внутренние ресурсы только для интерфейсов, на которые ссылаются.

Не все вызовы счетчика ссылок отправляются удаленным объектам по сети; Прокси-сервер хранит только одну ссылку на удаленный объект и поддерживает свой собственный локальный счетчик ссылок. Чтобы упростить разработку COM, Microsoft представила ATL (активную библиотеку шаблонов) для разработчиков на C ++. ATL обеспечивает парадигму разработки COM более высокого уровня. Он также защищает разработчиков клиентских приложений COM от необходимости напрямую поддерживать подсчет ссылок, предоставляя объекты интеллектуальных указателей . Другие библиотеки и языки, поддерживающие COM, включают классы Microsoft Foundation , поддержку COM компилятора VC , VBScript , Visual Basic , ECMAScript ( JavaScript ) и Borland Delphi .

Программирование

COM - это не зависящий от языка двоичный стандарт, который может быть разработан на любом языке программирования, способном понимать и реализовывать его двоично определенные типы данных и интерфейсы. Реализации COM отвечают за вход в среду COM и выход из нее, создание экземпляров и подсчет ссылок COM-объектов, запросы объектов для поддерживаемых интерфейсов, а также обработку ошибок. Компилятор Microsoft Visual C ++ поддерживает расширения языка C ++, называемые атрибутами C ++ . Эти расширения предназначены для упрощения разработки COM и удаления большей части шаблонного кода, необходимого для реализации серверов COM на C ++.

Использование реестра

В Windows классы COM, интерфейсы и библиотеки типов перечислены по идентификаторам GUID в реестре в разделе HKEY_CLASSES_ROOT \ CLSID для классов и HKEY_CLASSES_ROOT \ Interface для интерфейсов. COM-библиотеки используют реестр для поиска либо правильных локальных библиотек для каждого COM-объекта, либо сетевого расположения для удаленной службы.

COM без регистрации

Учетно-Free COM (RegFree COM) является технология введена с Windows XP , что позволяет Component Object Model (COM) компоненты для активации хранения метаданных и CLSID ( Class ID) для компонента без использования реестра . Вместо этого метаданные и идентификаторы CLSID классов, реализованных в компоненте, объявляются в манифесте сборки (описанном с помощью XML ), сохраняются либо как ресурс в исполняемом файле, либо как отдельный файл, установленный вместе с компонентом. Это позволяет устанавливать несколько версий одного и того же компонента в разные каталоги, описываемые их собственными манифестами, а также развертывать XCOPY . Этот метод имеет ограниченную поддержку для COM-серверов EXE и не может использоваться для общесистемных компонентов, таких как MDAC , MSXML , DirectX или Internet Explorer .

Во время загрузки приложения загрузчик Windows ищет манифест. Если он присутствует, загрузчик добавляет из него информацию в контекст активации. Когда фабрика классов COM пытается создать экземпляр класса, сначала проверяется контекст активации, чтобы увидеть, можно ли найти реализацию для CLSID. Реестр сканируется только в случае сбоя поиска .

Создание экземпляров COM-объектов вручную

COM-объекты также могут быть созданы вручную, учитывая путь к DLL- файлу и GUID объекта. Это не требует регистрации DLL или GUID в системном реестре и не использует файлы манифеста. COM-DLL экспортирует функцию с именем DllGetClassObject. Вызов DllGetClassObject с желаемым GUID и IID_IClassFactory предоставляет экземпляр фабричного объекта . У объекта Factory есть метод CreateInstance, который может создавать экземпляры объекта по GUID интерфейса. Это тот же процесс, который используется внутри компании при создании экземпляров зарегистрированных компонентов COM.

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

Прозрачность процессов и сети

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

Резьба

В COM многопоточность решается с помощью концепции, известной как апартаменты . Отдельный COM-объект находится ровно в одном апартаменте, который может быть однопоточным или многопоточным. В COM есть три типа квартир: однопоточные апартаменты (STA) , многопоточные апартаменты (MTA) и апартаменты с нейтральной резьбой (NA). Каждая квартира представляет собой один механизм, посредством которого внутреннее состояние объекта может быть синхронизировано в нескольких потоках. Процесс может состоять из нескольких COM-объектов, некоторые из которых могут использовать STA, а другие могут использовать MTA. Все потоки, обращающиеся к COM-объектам, аналогично живут в одной квартире. Выбор квартиры для COM-объектов и потоков определяется во время выполнения и не может быть изменен.

Тип квартиры Описание
Однопоточная квартира ( STA ), (ThreadingModel = Apartment ) Один поток предназначен для выполнения методов объекта. При таком расположении вызовы методов из потоков за пределами подразделения упорядочиваются и автоматически ставятся в очередь системой (через стандартную очередь сообщений Windows). Таким образом, среда выполнения COM обеспечивает автоматическую синхронизацию, чтобы гарантировать, что каждый вызов метода объекта всегда выполняется до завершения перед вызовом другого. Поэтому разработчику не нужно беспокоиться о блокировке потоков или условиях гонки.
Многопоточная квартира ( MTA ), (ThreadingModel = Free ) Среда выполнения COM не обеспечивает синхронизации, и нескольким потокам разрешено одновременно вызывать COM-объекты. Поэтому COM-объекты должны выполнять свою собственную синхронизацию, чтобы предотвратить одновременный доступ из нескольких потоков, вызывающий состояние гонки. Вызовы объекта MTA из потока в STA также упорядочиваются.
Динамически определяемая квартира (ThreadingModel = Both ) В режиме « Оба апартамента» сервер автоматически выбирает STA или MTA при создании объекта в соответствии с типом апартамента вызывающего потока. Это может быть полезно, чтобы избежать накладных расходов на маршалинг, когда к серверам MTA обращается поток STA.
Нейтральная квартира ( NA ), (ThreadingModel = Neutral ) Особая квартира без назначенных потоков. Когда поток STA или MTA вызывает объект NA в том же процессе, вызывающий поток временно покидает свою квартиру и выполняет код непосредственно в NA без переключения потоков. Следовательно, можно рассматривать NA как оптимизацию для эффективных вызовов методов взаимодействия.

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

Критика

Поскольку COM имеет довольно сложную реализацию, программисты могут отвлекаться на некоторые «сантехнические» вопросы.

Прокачка сообщений

Когда STA инициализируется, он создает скрытое окно, которое используется для маршрутизации сообщений между подразделениями и между процессами. Очередь сообщений этого окна должна регулярно «прокачиваться». Эта конструкция известна как « насос сообщений ». В более ранних версиях Windows невыполнение этого требования могло вызвать общесистемные взаимоблокировки. Эта проблема усложняется некоторыми Windows API, которые инициализируют COM как часть своей реализации, что вызывает «утечку» деталей реализации.

Подсчет ссылок

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

DLL ад

Поскольку внутрипроцессные COM-компоненты реализованы в файлах DLL, а регистрация допускает только одну версию для каждого CLSID, в некоторых ситуациях они могут подвергаться эффекту « DLL Hell ». Возможность COM без регистрации устраняет эту проблему для внутрипроцессных компонентов; COM без регистрации недоступен для внепроцессных серверов.

Смотрите также

Примечания

использованная литература

внешние ссылки