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

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

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

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

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

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

Следующая таблица показывает возможные виды сущностей: Сущность Члены Type Kind Название идентификатора Перечисление (Enum) Константы TKIND_ENUM — Объединение (Union) Поля объединения TKIND_UNION — СтруктураПо терминологии C/C++ — структура (struct), по терминологии Паскаля — запись (record), по терминологии Visual Basic — пользовательский тип (User-Defined Type, UDT). Поля структуры TKIND_RECORD — COM-интерфейсМетоды, свойства, поля класса, события TKIND_INTERFACEIID (Interface ID) Disp-интерфейсCOM-интерфейс, унаследованный от IDispatch, обеспечивающий поддержку позднего связывания с помощью IDispatch::Invoke. TKIND_DISPATCHCOM-классПоддерживаемые 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Загрузка осуществляются силами OLE Automation, а не разработчика..

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

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

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

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

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

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

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

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

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

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

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

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

Создание

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

Ручное

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

[ odl, uuid(D8F015C0-C278-11CE-A49E-444553540000), helpstring("Definition of interface IShellDispatch"), hidden, dual, oleautomation ] interface IShellDispatch : IDispatch { [id(0x60020000), propget, helpstring("Get Application object")] HRESULT Application([out, retval] IDispatch** ppid); [id(0x60020001), propget, helpstring("Get Parent object")] HRESULT Parent([out, retval] IDispatch** ppid); [id(0x60020002), helpstring("Get special folder from ShellSpecialFolderConstants")] HRESULT NameSpace( [in] VARIANT vDir, [out, retval] Folder** ppsdf); [id(0x60020003), helpstring("Browse the name space for a Folder")] HRESULT BrowseForFolder( [in] long Hwnd, [in] BSTR Title, [in] long Options, [in, optional] VARIANT RootFolder, [out, retval] Folder** ppsdf); [id(0x60020004), helpstring("The collection of open folder windows")] HRESULT Windows([out, retval] IDispatch** ppid); [id(0x60020005), helpstring("Open a folder")] HRESULT Open([in] VARIANT vDir); [id(0x60020006), helpstring("Explore a folder")] HRESULT Explore([in] VARIANT vDir); [id(0x60020007), helpstring("Minimize all windows")] HRESULT MinimizeAll(); [id(0x60020008), helpstring("Undo Minimize All")] HRESULT UndoMinimizeALL(); [id(0x60020009), helpstring("Bring up the file run")] HRESULT FileRun(); [id(0x6002000a), helpstring("Cascade Windows")] HRESULT CascadeWindows(); [id(0x6002000b), helpstring("Tile windows vertically")] HRESULT TileVertically(); [id(0x6002000c), helpstring("Tile windows horizontally")] HRESULT TileHorizontally(); [id(0x6002000d), helpstring("Exit Windows")] HRESULT ShutdownWindows(); [id(0x6002000e), helpstring("Suspend the pc")] HRESULT Suspend(); [id(0x6002000f), helpstring("Eject the pc")] HRESULT EjectPC(); [id(0x60020010), helpstring("Bring up the Set time dialog")] HRESULT SetTime(); [id(0x60020011), helpstring("Handle Tray properties")] HRESULT TrayProperties(); [id(0x60020012), helpstring("Display shell help")] HRESULT Help(); [id(0x60020013), helpstring("Find Files")] HRESULT FindFiles(); [id(0x60020014), helpstring("Find a computer")] HRESULT FindComputer(); [id(0x60020015), helpstring("Refresh the menu")] HRESULT RefreshMenu(); [id(0x60020016), helpstring("Run a Control Panel Item")] HRESULT ControlPanelItem([in] BSTR szDir);

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