Interested Article - Type library

TLB ( англ. T ype L i b rary — библиотека типов) — иерархическое хранилище информации о возможностях ActiveX-сервера в OLE Automation.

Библиотека типов — одно из ключевых понятий технологии OLE Automation . Библиотека типов представляет собой иерархическое (трёхуровневое, считая корневой элемент) хранилище информации о возможностях ActiveX -сервера. Чаще всего библиотека типов хранится либо как отдельный файл с расширением «.tlb» или «.olb», либо внутри (в ресурсах ) ActiveX-компонента , который она описывает. Кроме того, библиотека типов может находиться в составном документе OLE.

Причины создания

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

Логическая структура

Библиотека типов является трёхуровневым иерархическим хранилищем: вершиной иерархии является сама библиотека ( англ. Type Library ), представляющая собой набор типоописаний ( англ. Type Info ), являющихся, в свою очередь, контейнерами элементов третьего уровня — членов ( англ. Member ).

Все три типа элементов имеют одинаковый набор базовых характеристик:

Кроме того, библиотека и типоописания имеют уникальные 128-битные идентификаторы , а члены — 32-битные (уникальные в пределах одного типоописания). Идентификатор библиотеки называется LIBID , члена — MEMBERID . Название идентификатора типоописания зависит от вида типоописания.

В библиотеке типов могут описываться сущности восьми различных видов. Каждое типоописание определяет одну из них. В соответствии с этим, атрибутом типоописания, имеющим первостепенную важность при разборе типоописания, является вид типоописания ( англ. Type Kind ). Этот атрибут устанавливает вид сущности, описываемой данным типоописанием, и, тем самым, задаёт способ интерпретации всех прочих параметров и подчинённых элементов типоописания.

Следующая таблица показывает возможные виды сущностей:

Сущность Члены Type Kind Название идентификатора
Перечисление (Enum) Константы TKIND_ENUM
Объединение (Union) Поля объединения TKIND_UNION
Структура Поля структуры TKIND_RECORD
COM-интерфейс Методы ,
свойства ,
поля класса ,
TKIND_INTERFACE IID (Interface ID)
Disp-интерфейс TKIND_DISPATCH
COM-класс Поддерживаемые COM-интерфейсы TKIND_COCLASS CLSID (Class ID)
TKIND_ALIAS
Обычный модуль Функции ,
свойства,
переменные
TKIND_MODULE

Значение

TLB содержит ряд важной информации, необходимой как при разработке, так и в процессе работы приложений.

  • Описание метода интерфейса в числе прочего содержит:
    • Смещение ячейки данного метода в VTable . Компилятор может сгенерировать код, осуществляющий вызов метода по типу раннего связывания , только если ему известно смещение.
    • DispId (для Disp-интерфейсов) — особый числовой идентификатор метода. Компилятор может сгенерировать код, осуществляющий вызов метода по типу позднего связывания по DispId’у , только если ему известно значение этого идентификатора. В противном случае, возможно только позднее связывание по имени метода.
    • Соглашение о вызове . При использовании раннего связывания генерация осуществляющего вызов кода принципиально невозможна, если не известно используемое соглашение.
  • Описание функции из модуля содержит информацию о динамической библиотеке , экспортирующей данную функцию, её (функции) экспортное имя и/или ординал. Компилятор может сгенерировать корректную таблицу импорта, только если он обладает всеми этими сведениями.
  • Описания интерфейсов и классов содержат информацию об их уникальных идентификаторах (IID и CLSID соответственно). Программа не может запросить у OLE создание объекта требуемого класса, если не известен его CLSID, или запросить у объекта требуемый интерфейс, если не известен его IID.
  • Описания членов интерфейсов и модулей содержат информацию о количестве и типах параметров, о типах возврата (то есть прототипы ), что позволяет компилятору проверить правильность вызовов.
  • Библиотека типов содержит информацию, необходимую для осуществления маршалинга .
  • При поддержке средой разработки , ощутимую помощь разработчику оказывают краткие описания элементов библиотеки. Кроме того, разработчик может «встать» кареткой на интересующий идентификатор и (обычно нажатием F1) получить подробную справочную информацию по нему, благодаря тому, что для каждого элемента может храниться ссылка на файл справки и соответствующую справочную статью.
  • Технологии автодополнения , такие как IntelliSense , могут использовать библиотеки типов как источник информации.
  • Во время работы программы, имея ссылку на неизвестный объект, можно получить о нём почти всю информацию, при условии, что он поддерживает интерфейс ITypeInfo. В этом случае чаще всего объект, чтобы предоставить информацию о себе, использует ITypeInfo, полученный в результате загрузки своей же TLB .

C точки зрения хранимых сведений, библиотека является более продвинутым аналогом заголовочных файлов .

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

Программное

OLE API предлагает функции , позволяющие загрузить библиотеку типов и работать с ней через интерфейсы ITypeLib и ITypeLib2, а с хранящимися в ней сущностями — через ITypeInfo и ITypeInfo2.

Языки программирования и среды разработки

Microsoft Visual Basic

Для Visual Basic поддержка TLB является естественной и неотъемлемой, так как это единственный механизм, позволяющий привнести в пространство имён проекта информацию об уже существующих интерфейсах, классах, типах: язык позволяет объявлять свои, новые интерфейсы и классы, но не уже существующие . Так, например, большинство «встроенных» функций, типов, классов и интерфейсов языка объявлены в соответствующих библиотеках типов.

Библиотека типов подключается к проекту через Project→References (или косвенно, через Project→Components). Несколько «базовых» библиотек подключены изначально и не поддаются отключению.

Microsoft Visual C++

MSVC++ дополнен специальной директивой препроцессора #import , создающей для подключаемой библиотеки типов отдельное пространство имён , а для каждой описанной в библиотеке сущности — соответствующее C++-совместимое объявление.

Пример:

// Импорт библиотеки типов по имени tlb-файла
#import "../tlb/foobar.tlb"

// Импорт библиотеки типов из ресурсов PE-файла
#import "winhttp.dll"

// Импорт библиотеки по её LIBID'у
#import "libid:12341234-1234-1234-1234-123412341234"

Borland Delphi и Borland C++ Builder

В этих средах разработки имеется мастер импорта компонентов ( англ. Import Component Wizard ), доступный через меню Component→Import Component, позволяющий сгенерировать на основе библиотеки типов соответствующий pas- или h-файл с объявлениями.

PHP

В PHP имеется функция , которая загружает библиотеку типов и регистрирует в пространстве имён PHP константы из этой библиотеки. Функция выводит адаптированный дамп типоописания указанного класса/интерфейса.

Создание

Программное

OLE API предоставляет функции CreateTypeLib, CreateTypeLib2, интерфейсы ICreateTypeLib, ICreateTypeLib2, ICreateTypeInfo, ICreateTypeInfo2, с помощью которых задача создания и сохранения произвольной библиотеки типов решается программно. Разработчики могут создавать свои собственные приложения для создания библиотек типов, пользуясь этими API-функциями и интерфейсами.

Ручное

Для разработки библиотек типов Microsoft создала специальный язык MIDL . Исходные файлы, написанные на этом языке, компилируются с помощью одноимённой утилиты-компилятора midl.exe . Раньше для этих целей использовался mktyplib.exe , который в данное время считается устаревшим и не рекомендован к использованию. Существует значительная разница между требованиями этих двух утилит к входным данным: далеко не всякий код, верный для первого, будет верен для второго, и наоборот .


Расширяемость

Формат файла библиотеки типов предусматривают возможность расширения набора хранимых в библиотеке сведений. Для того, чтобы сохранить в библиотеке некоторую информацию, хранение которой изначально не предусмотрено, существует возможность снабдить любой элемент иерархии (библиотеку, типоописание, член), а также параметр метода/функции блоком произвольных данных ( англ. Custom Data ).

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

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

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


Прочее

Утилиты

Следующие утилиты могут быть использованы при работе с библиотеками типов:

  • MIDL (конс.)
    Компилятор языка MIDL, создаёт TLB-файл на основе исходного кода.
  • MkTypLib (конс.)
    Устаревший и не рекомендованный к использованию компилятор для создания TLB-файлов. Синтаксис входных файлов отличается от оного у MIDL’а. При необходимости компиляции исходников, написанных в «старом стиле», рекомендуется использовать MIDL с ключом /mktyplib203 .
  • regtlib (конс.)
    Утилита для регистрации библиотек типов в реестре .
  • regsvr32 (оконн.)
    Утилита для регистрации ActiveX-серверов в реестре. При регистрации обычно косвенным образом регистрируется и TLB, хранящаяся в ресурсах ActiveX-сервера.
  • Microsoft OLE View (оконн.)
    Утилита, отображающая список всех зарегистрированных в системе библиотек типов, позволяющая также просматривать содержимое любой из них. Способна восстанавливать исходный код просматриваемого элемента (всей библиотеки/типоописания/члена). Поставляется вместе с Microsoft Visual Studio 6.0 .
  • Обозреватель объектов ( англ. Object Browser ) в Visual Basic есть не что иное, как обозреватель подключенных к проекту библиотек типов.

Нецелевое использование

При разработке в среде Visual Basic библиотеки типов нередко используются не по своему прямому назначению, а для осуществления раннего импорта обычных WinAPI -функций , как единственно возможный в VB вариант осуществления импорта через таблицу импорта.

Примечания

  1. Который, в свою очередь, является PE-файлом и имеет расширение «.dll», «.ocx», «.cpl», «.exe» и т. д.
  2. По терминологии C / C++ — структура (struct), по терминологии Паскаля — запись (record), по терминологии Visual Basic — пользовательский тип (User-Defined Type, UDT).
  3. COM-интерфейс, унаследованный от IDispatch, обеспечивающий поддержку с помощью IDispatch::Invoke.
  4. Загрузка осуществляются силами OLE Automation, а не разработчика.
  5. Поскольку хранит в себе гораздо больше полезной информации, компактнее и быстрее (не нужно делать парсинг) заголовочных файлов и, главное, может использоваться в любой среде разработки и любом языке программирования, которые поддерживает COM, а не только в C/C++.
  6. от 21 июля 2009 на Wayback Machine и от 4 февраля 2011 на Wayback Machine
  7. Ограничение заключается в невозможности указать IID/CLSID для объявляемого интерфейса/класса — идентификатор присваивается автоматически, что делает объявленные сущности принципиально несовместимыми с существующими.
  8. Это поведение отключается модификатором no_namespace . Подробнее см. в от 11 февраля 2010 на Wayback Machine
  9. от 27 мая 2010 на Wayback Machine (MSDN).
  10. Код получен в результате декомпиляции TLB утилитой Microsoft OLE/COM Object Viewer.
  11. от 19 июня 2010 на Wayback Machine (англ., MSDN).
  12. В противоположность позднему — с помощью Declare Sub/Function.
  13. В общем случае, никак не связанных с COM и, тем более, с OLE Automation.
Источник —

Same as Type library