Tlbimp windows 10 где находится

Глава 19

Взаимодействие с COM

Компоненты COM и компоненты .NET не являются по своей природе совместимыми, так как они опираются на различные внутренние архитектуры. К счастью, однако, компания Microsoft предоставляет средства в SDK .NET для создания прокси COM для компонентов .NET и прокси .NET для компонентов COM. Используя эти прокси вместе с парой других технологий, организации могут использовать унаследованные компоненты COM в своих проектах .NET и могут также использовать компоненты .NET в своих приложениях, не являющихся приложениями .NET.

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

Сравнение COM и .NET

COM обозначает «Компонентная объектная модель» (Component Object Model). Для новичков платформы Windows понимание того, что делает COM, может быть трудным, а понимание того, как она действует, может показаться почти невозможным. Для новичков, не интересующихся созданием драйверов устройств или работой на компанию Microsoft, появление .NET и компонентов .NET позволит избежать сложностей программирования COM. Однако, так как COM была до сегодняшнего дня все же существенной частью программирования Windows, желательно быть знакомым с тем, как она действует и какие преимущества она предоставляет.

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

Существует, по крайней мере, два недостатка у статической компоновки: она требует излишнего пространства памяти, размещая избыточные копии идентичных функций в нескольких исполнимых файлах, и, если обнаруживается ошибка в одной из стандартных функций, требуется перекомпиляция и повторное распространение всех исполнимых файлов, использующих эту функцию. Чтобы избежать таких проблем, разработчики нашли способ компилировать библиотеки функций в автономные двоичные файлы, которые могут динамически компоноваться различными исполнимыми файлами. С помощью этой схемы несколько исполнимых программ могут совместно использовать один и тот же двоичный файл динамически компонуемой библиотеки (Dynamic Link Library, DLL). Если требуется исправить ошибку в служебной функции, можно просто распространить заново DLL, в которой находится эта функция, без перекомпиляции или повторного распространения всех исполнимых файлов, которые ее используют.

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

COM была следующим шагом в эволюции повторного использования кода. С ее помощью программисты могли написать библиотеку классов на таком языке, как C++, откомпилировать библиотеку и использовать классы этой библиотеки из другого совместимого с COM языка программирования, такого как Delphi или Visual Basic. COM был технологией, лежащей в основе других технологий, таких как OLE (Связывание и встраивание объектов) и элементов управления ActiveX.

Службы COM+ — последняя версия технологии COM, первоначально известная как Сервер транзакций Microsoft, является частью операционной системы Windows 2000, которую компоненты COM могут использовать для общей, необходимой компонентам, функциональности: поддержки транзакций, обеспечения безопасности и события, что позволит сохранить программистам COM ценное время разработки. Более подробно об этом рассказывается в следующей главе.

Принципы работы COM

Чтобы понять, почему компоненты COM и компоненты .NET внутренне несовместимы, необходимо иметь общее понимание того, как работает COM. Далее следует существенно упрощенное объяснение. Более детальную информацию можно найти в книге «Professional COM Applications with ATL» издательства Wrox Press (ISBN 1861001703).

Читайте также:  Нет службы центр обеспечения безопасности windows 10

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

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

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

Недостатки COM

Хотя COM предоставляет значительные преимущества, она имеет также недостатки. Первое: компоненты COM могут быть трудными для кодирования. В C++ разработка компонента COM включает реализацию стандартных интерфейсов COM и использование GUIDGEN.EXE для того, чтобы генерировать GUID для каждого класса и каждого интерфейса. (Хотя технологии, подобные VB и ATL Object Wizard упрощают процесс создания COM, они обеспечивают только подмножество свойств COM).

Второе: компоненты COM могут оказаться трудными для развертывания. Разработчики COM серверных компонентов предполагали обеспечить совместимость новых версий компонентов с более старыми, но не всегда это удавалось, поэтому установка нового приложения, которое ссылается на новую версию компонента COM, может внезапно дать отказ существующих приложений. Проблемы такого рода называются «адом DLL» и являются причиной большой головной боли и потерь времени.

Дополнительная информация о том, как .NET обращается с адом DLL, находится по адресу msdn.microsoft.com/library/techart/dplywithnet.htm.

Как работают компоненты .NET

Подход .NET к созданию компонентов использует многие возможности COM, игнорируя при этом ее недостатки. Компоненты должны иметь некоторый способ описания клиентам классов, которые они поддерживают. Вместо использования для этого GUID и реестра каждый файл компонента .NET инкапсулирует свое собственное описание во внутреннем сегменте, называемом манифестом (manifest).

Это означает, что размещение компонента выполняется просто: надо скопировать компонент .NET в папку исполнимого файла, который на него ссылается. Когда исполнимому файлу необходимо создать компонент, он просматривает в файле компонента в манифесте информацию, которая ему нужна. Различные версии одного и того же компонента могут существовать бок о бок на одной машине до тех пор, пока они хранятся в различных папках. (Существует центральная папка для хранения компонентов, которую можно сделать доступной для множества компонентов, она называется иногда «Global Assembly Cache» — Глобальный кэш сборок (см. главу 8).

Компоненты .NET также легко создавать в C# и VB.NET разработчик защищен от процесса создания манифеста. Разработчик создает просто проект библиотеки классов, заполняет его классами и позволяет компилятору выполнить грязную работу предоставления этих классов клиентам.

COM или .NET?

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

Однако для разработки на уровне предприятия может оказаться, что компоненты .NET окажутся более практичными, чем компоненты COM. В организациях, которые действуют со скоростью Интернет, достаточно хорошее программное обеспечение, сделанное вовремя, предпочтительнее оптимизированного программного обеспечения, которое опоздало на шесть месяцев. Если программное обеспечение запускается с сервера Web, то можно гарантировать, что среда выполнения .NET правильно сконфигурирована, и таким образом получается выигрыш от сохраненного времени разработки и развертывания, что обеспечивает платформа .NET.

Читайте также:  Пакет wine для linux mint

Речь не идет о том, что компоненты COM лучше, чем сборки .NET, или что сборки .NET лучше, чем компоненты COM. Сборки .NET, хотя и требуют больше поддержки во время выполнения, делают компонентную архитектуру более доступной для программистов.

Использование компонентов COM в .NET

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

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

Диалоговое окно ссылок

Прежде чем погружаться в тонкости вопросов взаимодействия с унаследованными объектами COM, давайте кратко обсудим, как достичь такого взаимодействия. Наше объяснение строится с точки зрения IDE VS.NET, так как большинство читателей будут использовать его для написания своих программ C#, но альтернативные редакторы могут предоставить свои собственные эквивалентные методы.

Для этого понадобиться использовать диалоговое окно ссылок (References Dialog), которое доступно из пункта меню Add Reference… в меню Project IDE Visual Studio.NET. Это диалоговое окно имеет три вкладки, первая из которых просто перечисляет DLL, которые являются вспомогательными, но при этом очень важными для среды времени выполнения платформы .NET.

Самая правая вкладка, Projects, перечисляет все проекты .NET, на которые ссылаются в данном решении. На следующем экране, например, клиентское приложение C# для онлайновых заказов опирается на несколько проектов библиотек классов C#, которые реализуют бизнес-правила. (Конечно, они не обязаны быть проектами C#, чтобы на них ссылался клиент C#, они могут также легко быть проектами VB.NET. Фактически, один клиент .NET может одновременно ссылаться на проекты компонентов на нескольких различных языках платформы .NET).

Средняя вкладка, COM, является вкладкой для импортирования компонентов COM в проекте .NET.

В верхнем правом углу диалогового окна имеется кнопка Browse. При нажатии на эту кнопку появится другое диалоговое окно, которое позволит найти в файловой системе DLL COM, требующиеся проекту .NET:

Когда файл будет найден, добавляем его в список компонентов в панели формы COM:

После использования диалогового окна ссылок для нахождения DLL COM и добавления библиотеки к списку ссылок COM, можно использовать компонент COM в коде .NET. VS.NET создает пространство имен с таким же именем, как и у исходного компонента COM, и классы этого компонента COM помещаются в это пространство имен. Ссылки, создание экземпляров и вызов оболочки объекта COM производятся с таким же синтаксисом, как и у собственных объектов C#.

Посмотрим на следующий пример кода. В нем определен метод для добавления нового заказчика в базу данных. В качестве аргумента ввода этот метод получает ссылку на объект

/// Этот код добавляет нового заказчика в базу данных,

/// обеспечивая при этом выполнение бизнес-правил.

public long AddNewCustomer(CustomerInfo objCustomerInfo) <

// Добавить запись в таблицу заказчиков.

objCustomerTable = new DataAccess.CustomerTable();

Конечно, если надоест вводить пространство имен компонента COM, то инструкция

// Размещение следующей инструкции в начале файла .

// позволяет ссылаться на классы DataAccess по их относительным именам

objCustomerTable = new CustomerTable();

IDE VS.NET будет даже использовать Intellisense, чтобы помочь запомнить членов класса компонента:

Читайте также:  Asus x58c драйвера linux

Intellisense поможет также с членами данных и списком аргументов.

Оболочки времени выполнения

Чтобы добавить ссылку на DLL COM при использовании диалогового окна References, IDE VS.NET делает некоторую работу за сценой. В частности, создается компонент прокси .NET для DLL COM и копия DLL COM помещается в каталог проекта .NET.

Вспомните, что компоненты .NET описывают сами себя, в то время как компоненты COM хранят свои описания в реестре. Прокси, который генерирует IDE VS.NET, описывает DLL COM и служит для нее в качестве делегата, пересылая вызовы от клиента .NET через службы COM в DLL COM, которую он обертывает. Клиент .NET не знает, что он вызывает компонент COM; он общается только с прокси и получает данные, которые прокси пересылает обратно из DLL COM.

В терминологии .NET такой прокси называется оболочкой времени выполнения, или RCW. IDE создает DLL, которая имеет такое же имя, как и исходный компонент COM, но является в действительности .NET RCW, которая просто обертывает первоначальный компонент, предоставляя его клиентам .NET через интерфейс .NET, который они могут понять. Интересное дополнительное замечание: IDE VS.NET создает оболочку не только для каждой импортируемой DLL COM, но для каждой DLL COM, на которую ссылается импортированная DLL COM в своем открытом интерфейсе, поэтому в этой папке будет также находиться файл

В рассматриваемом примере DLL COM,

TlbImp.exe

Опасно ли для RCW, созданной IDE VS.NET, иметь такое же имя, как и исходная DLL COM? В конце концов, если приложение переносится с одной машины на другую, будет очень легко спутать RCW с DLL COM, которую он заворачивает, и случайно перезаписать файл DLL COM. Или можно по ошибке попытаться зарегистрировать RCW в службах COM, удивляясь, почему программа регистрации (

Чтобы избежать таких проблем, попробуйте воспользоваться напрямую утилитой

В заключение пара предупреждении о

Второе: помните, что хотя RCW служит в качестве посредника между компонентом COM и клиентом .NET, который его вызывает, по-прежнему всю реальную работу делает компонент COM. То есть необходимо выполнить те же требования к развертыванию компонента COM, которые пришлось бы сделать, если бы он использовался напрямую. Это означает, что завернутый компонент COM тем не менее надо регистрировать в службах COM. Если попробовать сослаться на незарегистрированный компонент COM, то IDE VS.NET будет порождать ошибку.

Чтобы справиться с этой проблемой, понадобится, конечно, программа регистрации COM —

Поэтому не забывайте регистрировать компоненты COM.

Позднее связывание с компонентами COM

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

Программы с ранним связыванием узнают адреса на ранней стадии процесса компиляции/выполнения — во время компиляции. Когда программа (ранним связыванием компилируется, компилятор использует библиотеку типов компонента для включения адресов методов и свойств компонента в клиентскую исполнимую программу, чтобы к адресам можно было очень быстро и безошибочно обращаться. Технологии взаимодействия COM которые были рассмотрены до сих пор, используют раннее связывание.

Со своей стороны, программы с поздним связыванием узнают адреса свойств и методов на поздней стадии процесса компиляции/выполнения, в тот самый момент, когда эти свойства и методы вызываются. Код с поздним связыванием обычно обращается к клиентским объектам через базовые типы данных, такие как

Но сначала проверим, как позднее связывание выполняется с помощью отражения в C# (Отражение, является способом, который используется кодом во время выполнения для определения информации об интерфейсах серверных классов; см. главу 5.)

При позднем связывании с объектом COM в программе C# не нужно создавать RCW для компонента COM. Вместо этого вызывается метод класса

Оцените статью