Поиск

Генерация метаданных из библиотеки типов СОМ

Приложение .NET, которому требуется взаимодействие с нашим компонентом СОМ, не может непосредственно воспользоваться функциональностью этого компонента. Почему нет? Как нам известно из главы 16, .NET создана для работы с компонентами, у которых есть метаданные, тогда как СОМ работает через реестр и с помощью набора методов опроса, реализованных компонентом. Поэтому первое, что нам надо сделать, чтобы этот компонент СОМ применялся в .NET, — это сгенерировать для него метаданные. В случае компонента СОМ этот слой метаданных позволяет исполняющей среде определить информацию о типе. / Далее эта информация о типе используется в период выполнения для / создания сущности под названием оболочка, обеспечивающая обращение! в период выполнения (runtime callable wrapper, RCW — рис. 17-1). RCW реально активизирует объект СОМ и преобразует данные при взаимодеш ствии с приложением .NET. RCW также выполняет уйму другой работы: управление идентификационными данными и сроками жизни объекте^, а также кэширование интерфейсов. ,

Управление сроком жизни объектов — проблема важнейшая, так как .NET GC перемещает объекты и автоматически избавляется от них, когда они больше не используются. RCW создает для приложения .NET иллюзию того, что оно взаимодействует с управляемым компонентом .NET, а для компонента СОМ в неуправляемом пространстве она формирует впечатление, что его вызывает традиционный клиент СОМ. Создание и поведение RCW варьирует в зависимости от того, каким является связывание с объектом СОМ: ранним или поздним. Внутренние механизмы RCW выполняют всю черную работу и шлюзование вызовов всех методов в соответствующие vtable-вызовы компонента СОМ, живущего в неуправляемом мире. В основном она действует как посол доброй воли между управляемым миром и неуправляемым миром lUnknown. Но хватит болтать! Сгенерируем оболочку метаданных для нашего компонента COM Airlinelnfo. Для этого нам потребуется утилита Туре \ Library Importer (tlbimp.exe). Эта утилита, поставляемая с .NET SDK, слу-\ жит для считывания библиотеки типов СОМ и генерации соответствующей оболочки метаданных, содержащей информацию о типе, понятную исполняющей среде .NET. Для этого нам нужно установить демо-приложения с CD, прилагаемого к книге, и найти компонент Airlinelnfo. ' Сделав это, наберите в командной строке:

HBIMP Airlinelnformation.tlb /out:AirlineMetadata.dll

Эта команда заставляет TLBIMP прочитать библиотеку типов COM Airlinelnfo и сгенерировать соответствующую оболочку метаданных с именем AirlineMetadata.dll. Если все будет работать, как надо, вы увидите сообщение:

TypeLib imported successfully to AirlineMetadata.dll

Какую информацию о типах содержат эти метаданные и как она выглядит? Как и все работающие с СОМ, вы молились на нашу любимую утилиту OleView.exe — ведь она, помимо прочего, позволяет нам изучать содержимое typelibl К счастью, в поставку .NET SDK входит нечто похожее — дизассемблер IL под названием ILDASM, с которым вы познакомились в главе 2. Он позволяет просматривать метаданные и код MSIL, сгенерированный для управляемых сборок. Как вы узнали из главы 16, каждая управляемая сборка содержит самоописывающиеся метаданные, a ILDASM — очень полезный инструмент для просмотра этих метаданных. Итак, откроем AirlineMetadata.dll с помощью ILDASM (рис. 17-2).

Просматривая сгенерированные метаданные, вы можете заметить, что метод GetAirlineTiming указан как открытый член класса Airlinelnfo. Там присутствует и конструктор этого класса. Заметьте, что параметры метода были автоматически замещены своими эквивалентами в .NET. В этом примере BSTR был заменен параметром System.String. Обратите внимание и на то, что параметр с пометкой [out,retval] метода GetAirlineTiming был преобразован в реальное значение, возвращаемое методом (в виде System.String). Кроме того, любые значения ошибок HRESULT, возвращаемые компонентом СОМ в случае ошибки или сбоя прикладной логики, ведут к генерации исключений.