Королевство Дельфи"Knowledge itself is power"
F.Bacon
 Лицей
  
Главная
О лицее

Список семинаров

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  04:11[Войти] | [Зарегистрироваться]

Урок 13. Библиотека типов

Антон Григорьев
дата публикации 10-06-2008 09:28

урок из цикла: Использование COM/DCOM в Delphi


предыдущий урок содержание семинара следующий урок

Урок 13. Библиотека типов

В предыдущем уроке мы уже упоминали про библиотеку типов — специальный файл с расширением tlb, содержащий информацию, с помощью которой стандартная библиотека oleaut32.dll строит заглушку и заместитель для интерфейса. Уже из этого можно сделать вывод, что библиотека типов содержит описание методов интерфейса и их параметров.

Действительно, библиотека типов — это файл (обычно — с расширением tlb) в специальном двоичном формате, который может содержать описание интерфейсов, а также пользовательских типов и коклассов. Это описание пришло из технологии OLE и первоначально не распространялось на COM в целом. Но постепенно возможности библиотеки типов расширялись, и теперь практически полностью перекрывают потребности в описании COM-интерфейсов и серверов. Это описание требуется не только для автоматизированного построения заглушки и заместителя, ему находится множество применений. Одно из самых главных — возможность передачи информации об интерфейсах не зависящим от языка написания способом. Действительно, если вы разработали интерфейс и распространяете его описание в исходных кодах на Delphi, не факт, что человек, который захочет написать клиент, например, на Visual Basic, сможет корректно перевести ваше описание на свой язык. Если же вы передадите ему библиотеку типов, он откроет её в своей среде, и она автоматически сгенерирует описание интерфейса на нужном ему языке. Разумеется, если среда поддерживает работу с библиотеками типов.

Delphi позволяет как создавать свои библиотеки типов, так и генерировать код на Паскале на основе существующих библиотек. Рассмотрим, как можно создавать новые библиотеки типов. Для этого открываем окно создания нового объекта с помощью меню File/New/Other, находим вкладку ActiveX, а на ней — ярлык Type Library. Открывается окно, показанное на рисунке 1.


Рисунок 1. Окно редактора библиотеки типов

Библиотека типов содержит объекты (в широком смысле этого слова), которые имеют атрибуты. Объекты могут быть вложены друг в друга (например, метод вложен в интерфейс). Левая часть окна на рисунке 1 содержит дерево объектов библиотеки типов. Сама библиотека типов также рассматривается как объект, в который вложены все остальные. Соответственно, библиотека типов имеет атрибуты. В правой части окна на рисунке 1 мы видим вкладку Attributes, на которой показаны атрибуты выбранного объекта. Атрибуты можно рассматривать как свойства объекта, которые могут принимать те или иные значения. Например, значения атрибута Name библиотеки типов задаёт её имя. Ещё у объектов есть флаги (они расположены на вкладке Flags) — специальные свойства объектов, которые могут быть либо включены, либо выключены. Вкладка Uses содержит список библиотек, которые импортируются создаваемой нами библиотекой. Импортирование означает, что становятся доступны все объекты, объявленные в импортируемой библиотеке: при описании методов можно использовать для параметров её типы, при создании интерфейсов — наследоваться от её интерфейсов и т.п. Стандартная системная библиотека stdole2.tlb импортируется всеми библиотеками типов, так как в ней сделаны все базовые объявления. Наконец, вкладка Text содержит описание библиотеки типов на языке IDL, который мы рассмотрим на одном из следующих уроков.

Примечание: Язык, использующийся для описания библиотеки типов в Delphi, можно менять. Для этого надо с помощью меню Tools\Environment options открыть диалоговое окно, выбрать там вкладку Type Library, и в поле Language сменить IDL на Pascal. Впрочем, некоторые особенности IDL не имеют аналога в Паскале, поэтому на самом деле для описания будет использоваться нечто паскалеобразное, этакая помесь Паскаля и IDL. Возможно, это будет полезно для тех, кто совсем не привык к синтаксису C/C++, который использует IDL.

Вернёмся к объектам, которые может содержать библиотека типов. Если мы щёлкнем правой кнопкой мыши на дереве объектов, появится меню, содержащее пункт New, а в нём восемь доступных подпунктов, каждый из которых соответствует типу объекта, который можно поместить в библиотеку типов. Кратко рассмотрим все эти объекты:

Interface — описание COM-интерфейса. Это наиболее интересный для нас тип объекта, к нему мы вернёмся чуть ниже.

DispInterface — интерфейс диспетчеризации (в интернете его нередко называют "диспинтерфейс", но мы не будем пользоваться этим неуклюжим словом). С интерфейсами диспетчеризации мы ещё не сталкивались и обсудим их в одном из следующих уроков, а здесь больше к ним возвращаться не будем.

CoClass — хорошо знакомый нам кокласс. Разумеется, библиотека типов не может содержать реализацию кокласса, она содержит только его краткое описание: как называется, какой у него CLSID, какие интерфейсы содержит. Подробнее о коклассе мы тоже поговорим нижк.

Enum — перечислимый тип. Библиотека типов позволяет описывать не только интерфейсы, но и некоторые простые типы, к которым относится и перечисление. Перечисление в библиотеке типов по смыслу напоминает традиционное для C++, т.е. каждому идентификатору можно поставить в соответствие числовую константу, и эти константы не обязаны идти подряд. Если добавить в библиотеку типов объект Enum, а потом нажать правую кнопку мыши на нём, то в меню New можно увидеть доступный новый объект — Const. Это — отдельный элемент перечисления, который может иметь своё имя и значение. С помощью интуитивно понятного интерфейса можно создавать нужное количество элементов перечисления.

Alias — простейший пользовательский тип, синоним одного из уже существующих типов.

Record — тип-запись. Аналог record в Delphi, только не позволяет напрямую делать вариантные записи. Для этого объекта в меню New появляется новый тип вложенного объекта — Field, который представляет собой одно поле записи. Обратите внимание, что в выпадающем списке типов для полей отсутствуют многие допустимые типы, их названия, при необходимости, приходится набирать вручную.

Примечание: Если для текстового представления библиотеки типов выбран язык IDL, здесь и везде в редакторе типы надо вводить так, как они пишутся в этом языке, хотя редактор библиотеки типов в Delphi понимает и некоторые принятые для Паскаля имена. Так, целый тип можно записать и "int", и "Integer", но вот указатель на целое должен быть обязательно "int*" — ни "^int", ни "^Integer", ни "Integer*" здесь не подойдут. С интерфейсными типами ситуация тоже неоднозначная из-за того, что IDL вслед за C++ оперирует не самим интерфейсами, а явными указателями на них. Поэтому редактор Delphi допускает и написание "IUnknown", и "IUnknown*", воспринимая их одинаково — как дельфийский IUnknown. Следует быть осторожным и при использовании одноимённых типов, которые в разных языках означают разное. Например, shortint в Delphi — это однобайтное знаковое целое, а в C++ и IDL — двухбайтное. Поэтому тип shortint в редакторе библиотеки типов приводится к SmallInt при переводе на Delphi, а char, соответственно, переводится в ShortInt. Ещё раз напомним, что это всё относится к тому случаю, когда выбран язык IDL; при выборе Паскаля используются традиционные для Delphi названия типов.

Union — тип-объединение, аналог типа union в C/C++. Похож на запись, но все поля располагаются по одному адресу, т.е. это средство, аналогичное по смыслу вариантным записям в Delphi. С объединением возникают некоторые проблемы при маршалинге. Как мы помним, некоторые типы являются указателями на динамические данные, и при маршалинге между адресными пространствами следует передавать не значение самого указателя, а то содержимое, на которое он указывает. Допустим, одно поле объединения имеет тип Integer, а другое — BStr. Следует ли передавать строку, на которую указывает строковое поле? Это неизвестно, потому что в данный момент может использоваться целое поле, и тогда строковое поле будет содержать мусор. Как мы увидим дальше, при стандартном маршалинге к объединению обычно добавляется селектор — специальное значение, которое показывает, какое из полей в данный момент используется. Что же касается универсального маршалинга, то union не является VARIANT-совместимым типом и не может использоваться при этом виде маршалинга.

Module — этот объект включает в себя описания функций, экспортируемых DLL. Как известно, динамически компонуемые библиотеки не содержат в себе описание своих функций, что порождает немало проблем при их импорте. Так как библиотеку типов можно внедрить в ресурсы DLL, предполагалось, что с помощью объектов типа module можно исправить этот недостаток. Однако данная технология сколько-либо заметного распространения не получила. К тому же она не имеет отношения к COM, поэтому мы больше не будем на ней останавливаться.

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

Создадим с помощью Delphi интерфейс и посмотрим, какие возможности по его редактированию даёт редактор. На странице атрибутов появился атрибут Parent Interface — интерфейс, от которого наследуется данный интерфейс (строго говоря, это атрибутом не является, но разработчики Delphi поместили соответствующий элемент управления на страницу атрибутов). Обратите внимание, что по умолчанию Delphi предлагает интерфейс IDispatch, а не IUnknown. Это связано с тем, что поддержка COM в Delphi направлена прежде всего на автоматные и дуальные интерфейсы, которые наследуются от IDispatch (мы будем разбирать их чуть позже).

Из флагов нас интересуют пока только два: Hidden и OLE Automation. Флаг Hidden показывает, что данный интерфейс является скрытым, т.е. средства просмотра библиотеки типов не должны показывать его пользователю. Это используется для сокрытия устаревших интерфейсов (а также коклассов и целых библиотек типов): старые клиенты, которые и так знают, что в COM-сервере есть такие интерфейсы и т.п., будут их без помех использовать, а разработчик новых клиентов просто не узнает об их существовании.

Флаг OLE Automation показывает, что данный интерфейс маршалируется с помощью библиотеки oleaut32.dll, т.е. используется универсальный маршалинг. По умолчанию этот флаг недоступен, потому что включен другой флаг — Dual. Дуальными интерфейсами мы пока не занимаемся, поэтому первое время будем этот флаг отключать. Ещё один доступный флаг — Nonextensible — имеет смысл только для интерфейсов, унаследованных от IDispatch, о нём мы тоже поговорим позднее.

Примечание: Ещё раз напомним, что параметры методов интерфейсов, маршалируемых с помощью библиотеки типов, должны иметь VARIANTt-совместимые типы. Delphi не проверяет, выполняется ли это требование, так что за этим приходится следить самостоятельно.

Теперь добавим к интерфейсу метод (щёлчок правой кнопки мыши на интерфейсе в дереве объектов, New/Method). На странице атрибутов появляется имя метода и его идентификатор (обычное целое число, не GUID). Идентификатор имеет смысл только для интерфейсов, унаследованных от IDispatch, для остальных он игнорируется. Флаги, доступные для метода, мы здесь рассматривать не будем, так как они редко используются, перейдём сразу к параметрам. Параметры метода находятся на вкладке Parameters. Каждый параметр имеет имя, тип и набор модификаторов — флагов и атрибутов параметра. Параметры могут иметь следующие модификаторы:

МодификаторОписание
InПараметр является входным, т.е. через него вызывающая сторона передаёт данные вызываемой.
OutПараметр является выходным, т.е. через него вызываемая сторона возвращает данные вызывающей. Параметр должен быть указателем (т.е. значение передаётся по ссылке). Допускается указание для одного параметра модификаторов In и Out одновременно — в этом случае параметр является и входным, и выходным. Модификаторы In и Out очень важны для правильного маршалинга: без них библиотека oleaut32.dll не сможет правильно передавать параметры через границы процесса, так что забывать об этих модификаторах нельзя.
RetValЧерез данный параметр возвращается значение функции (этот модификатор допустим только для Out-параметров). Как мы уже говорили, для полной совместимости с COM/DCOM методы интерфейса должны возвращать значение типа HRESULT. Но некоторые языки программирования (например, Visual Basic) позволяют вызывать методы, имеющие параметр с модификатором RetVal так, как будто это функции, возвращающие RetVal-значение. RetVal-параметр должен быть последним в списке параметров.
LCIDПараметр является идентификатором языка. Если метод поддерживает несколько языков (имеются ввиду естественные языки, а не языки программирования), через этот параметр передаётся идентификатор языка. Параметр с данным модификатором должен иметь тип long и стоять в списке параметров либо последним, либо предпоследним непосредственно перед RetVal-параметром. Смысл данного модификатора в том, что некоторые среды программирования позволяют не указывать данный параметр явно, а автоматически при вызове подставляют идентификатор текущего языка.
OptionalПараметр является необязательным. Такой параметр должен иметь тип VARIANT или VARIANT*. Некоторые среды разработки позволяют при вызове метода не указывать необязательные параметры, передавая вместо них пустое (т.е. VT_EMPTY) значение.
Has Default ValueПараметр имеет значение по умолчанию (при выборе этого модификатора становится доступно поле ввода значения по умолчанию). По сути, то же самое, что и Optional-параметр, только вместо пустого значения передаётся заранее заданное. Параметры со значением по умолчанию могут иметь не только тип VARIANT, но и любой VARIANT-совместимый тип.

Примечание: Модификаторы In и Out влияют не только на направление передачи параметров, но и на то, кто отвечает за выделение и освобождение памяти для параметра. Но при использовании универсального маршалинга, когда доступны только VARIANT-совместимые типы, об этом можно вообще не беспокоиться, так как Delphi автоматически финализирует параметры в нужный момент (за исключением параметров типа PSafeArray; при использовании этого типа заботиться об освобождении памяти всё-таки надо). Об ответственности за выделение и освобождение памяти мы будем говорить в одном из следующих уроков при обсуждении стандартного маршалинга.

Кроме методов, в интерфейсы можно добавлять свойства. На самом деле в этом случае в интерфейс добавляется два метода: один с флагом propget для получения значения свойства, и второй с атрибутом propput — для его изменения. Многие среды программирования (включая Delphi) позволяют обходиться с этой парой методов как со свойством. Редактор библиотеки типов следит за тем, чтобы этим методы были синхронизированы, т.е. работали с одним типом, имели одинаковый набор дополнительных параметров и т.п.

Примечание: Система поддерживает также передачу значения свойства по ссылке — для этого вместо флага propput используется propputref. Но редактор библиотек типов в Delphi эту опцию не поддерживает, при необходимости её использования текст библиотеки типов на вкладке Text необходимо править вручную.

Следующее, что мы рассмотрим — это кокласс. Никаких специальных параметризованных атрибутов у кокласса нет, а из флагов нас пока интересует только Can Create (по умолчанию включен). Этот флаг показывает, что кокласс имеет регистрируемую в системе фабрику класса, т.е. может быть создан обычным образом.

На закладке Implements содержится список интерфейсов, реализуемых коклассом. Этот список должен включать в себя как минимум один интерфейс. Добавление интерфейса выполняется через пункт Insert Interface контекстного меню. Если открыть это меню на уже добавленном интерфейсе, в его нижней части можно увидеть четыре флага: Source, Default, Restricted и VTable. Пока нас интересует только Default. Этот флаг может быть установлен только у одного из интерфейсов кокласса. В тех языках программирования, где существуют, средства создания COM-объектов, более высокоуровневые, чем CoCreateInstance и прямое использование фабрики класса, эти средства возвращают указатель на тот интерфейс кокласса, который отмечен флагом Default (если ни один интерфейс таким флагом не отмечен, то возвращается указатель на IUnknown). Чуть ниже мы увидим, как Delphi использует этот флаг.

Если вы программируете в BDS 2005 и выше, вы могли заметить, что одновременно с файлом Project1.tlb в редакторе появился файл Project1_TLB.pas, содержащий описание библиотеки типов. В более ранних версиях Delphi этот файл сразу не появляется, но его можно легко увидеть, выбрав пункт меню View\Toggle Form/Unit (или кнопкой переключения между редактором формы и модуля в панели инструментов). При редактировании библиотеки типов этот файл автоматически не обновляется, для его обновления следует нажить кнопку Refresh Implementation в окне редактора библиотеки типов (первая кнопка в третьей группе кнопок панели инструментов, иконка такая же, как у кнопки "Обновить" в старых версиях Internet Explorer). Если в момент нажатия этой кнопки оказывается, что библиотека типов содержит ошибки (например, в одном коклассе два интерфейса отмечены как Default), pas-файл не обновляется, а информация об ошибке появляется в строке статуса редактора библиотеки типов. Будьте внимательны, потому что это сообщение рисуется обычным шрифтом, и его легко не заметить.

Если вы не создаёте новый tlb-файл, а открываете существующий, в Delphi 7 и более ранних версиях получение pas-файла выполняется точно так же — через кнопку Refresh Implementation. В более новых версиях эта кнопка почему-то не действует, а команда Toggle Form/Unit для библиотеки типов недоступна. Поэтому приходится деуствовать следующим образом: В меню Components выбираете пункт Import Component. В открывшемся мастере на первой странице выбираете Import Type Library. На следующей странице находите библиотеку типов среди зарегистрированных в реестре библиотек. На следующих страницах уточняете, что вы хотите создать (модуль, не устанавливающийся в палитру компонентов). После этого вы получаете нужный модуль.

Примечание: Этот пункт отсутствует в меню BDS 2006 и Turbo Delphi, если не установлен BDS 2006 Hotfix Rollup — пакет исправлений, который можно бесплатно получить на сайте CodeGear.

Конвертирование библиотеки типов в pas-файл тем способом, который используется в BDS 2006 и выше, не всегда удобен, так как требует предварительной регистрации библиотеки типов в реестре. Если нужно обойтись без регистрации, можно использовать утилиту tlibimp.exe, которая поставляется с Delphi. Пример использования этой утилиты мы рассмотрим на следующем уроке.

В получающемся после конвертирования pas-файле нет ничего неожиданного. Объявления простых типов и интерфейсов, сделанные в редакторе, переводятся на Паскаль очевидным образом. Добавляются константы с префиксами LIBID_ ( GUID библиотеки типов), IID_ (интерфейсов), DIID_ (интерфейсов диспетчеризации) и CLASS_ (коклассов; напомним, что здесь Delphi отступает от общепринятых правил, которые рекомендуют подобным константам давать префикс CLSID_).

Отдельного разговора заслуживает только то, как на Паскаль транслируется объявление коклассов. Рассмотрим это на конкретном примере. Пусть у нас есть кокласс CoClass1, который реализует интерфейсы Interface1 и Interface2, причём Interface1 имеет атрибут Default. Тогда в pas-файле мы увидим такое объявление типа:

CoCoClass1 = class
  class function Create: Interface1;
  class function CreateRemote(const MachineName: string): Interface1;
end;

Реализация этих методов достаточно проста:

class function CoCoClass1.Create: Interface1;
begin
  Result := CreateComObject(CLASS_CoClass1) as Interface1;
end;

class function CoCoClass1.CreateRemote(const MachineName: string): Interface1;
begin
  Result := CreateRemoteComObject(MachineName, CLASS_CoClass1) as Interface1;
end;

По сути дела, создана оболочка для создания экземпляров класса CoClass1, имеющая вид класса с двумя статическими функциями: для локального и для удалённого создания. Обе эти функции возвращают тот интерфейс, который является в коклассе интерфейсом по умолчанию. Впрочем, наличие такой оболочки не мешает при необходимости пользоваться рассмотренными ранее способами создания объектов — например, через фабрику класса. В каждом конкретном случае разработчик выбирает то, что ему удобнее.

Кроме типа CoCoClass1 объявлен также тип CoClass1 — это синоним Interface1 (интерфейса по умолчанию). Это сделано для возможности работы в тиле тех языков программирования, в которых нет отдельных интерфейсных типов, поэтому понятия "интерфейс" и "объект" почти сливаются. Подчеркнём, что ни CoCoClass1, ни CoClass1 не являются заготовками для реализации кокласса сервером. Эту реализацию нужно создавать отдельно.

Мы уже говорили, что библиотека типов может быть помещена в ресурсы exe— или dll-файла. Это должен быть ресурс типа "typelib", имеющий целочисленный идентификатор. Ресурсов может быть несколько. С помощью любого компилятора ресурсов (например, brcc32.exe, входящего в состав Delphi), можно помещать tlb-файлы в ресурсы, добавив в rc-файл примерно такие строки:

1 typelib TypeLib1.tlb
2 typelib TypeLib2.tlb

Для извлечения информации из библиотеки типов вручную разбирать формат tlb-файла нет нужды. В системе существует функции LoadTypeLib и LoadTypeLibEx. Эти функции возвращают интерфейс ITypeLib, через который можно получить всё содержимое библиотеки типов. Функции умеют загружать библиотеку типов как из отдельного tlb-файла, так и из ресурсов PE-файла. Идентификатор ресурса в последнем случае указывается после имени файла и отделяется от него обратным слэшем. Например, чтобы загрузить библиотеку типов, содержащуюся в ресурсах некоторого файла SomeProg.exe под номером 2, надо выполнить такой код:

LoadTypeLib('C:\SomePath\SomeProg.exe\2');

Самостоятельный разбор содержимого библиотеки типов — вещь довольно редкая, поэтому детально рассматривать интерфейс ITypeLib мы здесь не будем. Отметим только, что для каждого из типов, входящих в библиотеку, он позволяет получить интерфейс ITypeInfo, через который становится доступной информация об этом конкретном типе (здесь из-за некоторой путаницы в терминологии под типом подразумевается не только тип в обычном смысле этого слова, но также кокласс и модуль).

Если информация о типе передаётся через интерфейсы, возникает мысль: а не может ли объект быть "самодокументируемым"? Т.е. самостоятельно рассказывать о том, какие интерфейсы он реализует, какие методы эти интерфейсы содержат и т.п. Может, для этого предусмотрено два стандартных интерфейса: IProvideClassInfo и IDispatch. IProvideClassInfo содержит всего один метод GetClassInfo — он возвращает интерфейс ITypeLib, соответствующий коклассу, который реализует данный интерфейс.

Интерфейс IDispatch содержит четыре метода, но только два из них имеют отношение к предоставлению: GetTypeInfoCount и GetTypeInfo. По названиям этих методов можно сделать вывод, что COM-объект, реализующий IDispatch, может предоставлять информацию о нескольких типах, тем более что метод GetTypeInfo имеет параметр Index, в котором передаётся номер типа, информация о котором требуется. Но на самом деле GetTypeInfoCount может возвращать только 0 или 1, а параметр Index при вызове метода GetTypeInfo должен быть равен нулю. Таким образом, через эти методы можно вернуть информацию только о каком-то одном типе. Так, например, стандартные средства Delphi реализуют GetTypeInfo так, что он возвращает информацию об интерфейсе, отмеченном флагом Default.

Примечание: Предоставление информации о типе — не основная задача интерфейса IDispatch, методы GetTypeInfoCount и GetTypeInfo могут не возвращать информацию о типе, даже если она есть у сервера. Основная задача интерфейса IDispatch — обеспечивать работу автоматных интерфейсов, чем и занимаются остальные два метода. Этим методам будет посвящён отдельный урок.

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

Как мы уже говорили, библиотека типов может быть зарегистрирована в реестре. Для этого есть специальная системная функция RegisterTypeLib. Она регистрирует в реестре как саму библиотеку, так и все описанные в ней интерфейсы, которые могут маршалироваться библиотекой oleaut32.dll (т.е. все интерфейсы диспетчеризации, дуальные интерфейсы и интерфейсы с флагом oleautomation). Соответственно, парная ей функция, отменяющая регистрацию библиотеки типов, называется UnregisterTypeLib.

Функция LoatTypeLib тоже может регистрировать загружаемую библиотеку, если указано только имя файла без полного пути. Если же путь указан полностью, библиотека только загружается, но не регистрируется. Такое странное поведение требуется для обеспечения обратной совместимости. Функция LoadTypeLibEx отличается от LoadTypeLib тем, что регистрирует загружаемую библиотеку типов только в том случае, если это специально указано с помощью дополнительного параметра, независимо от того, задан или нет полный путь.

Утилиты, подобной regsvr32, с помощью которой можно было бы регистрировать библиотеки типов, в системе не предусмотрено. Но такая утилита поставляется в составе Delphi. Она находится в папке $(DELPHI)\Bin и называется tregsvr.exe. Эта утилита умеет регистрировать как внутренние COM-серверы, так и библиотеки типов. Утилита tregsvr доступна также в исходных кодах — она поставляется и как пример к Delphi. Точное положение этого проекта зависит от версии Delphi; в Delphi 7, например, он находится в папке $(DELPHI)\Demos\ActiveX\TRegSvr.


предыдущий урок содержание семинара следующий урок




Смотрите также материалы по темам:
[Технологии ActiveX, COM, DCOM] [Библиотеки типов]

 Обсуждение материала нет сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования