Delphi и COM


         

Поддержка IDispatch, тип данных Variant


Delphi имеет встроенную поддержку работы в качестве клиента Automation. Тип данных Variant может содержать ссылку на интерфейс IDispatch и использоваться для вызова его методов.

uses ComObj; procedure TForm1.Button1Click(Sender: TObject); var V: Variant; begin   V := CreateOleObject('InternetExplorer.Application');   V.Toolbar := FALSE;   V.Left := (Screen.Width - 600) div 2;   V.Width := 600;   V.Top := (Screen.Height - 400) div 2;   V.Height := 400;   V.Visible := TRUE;   V.Navigate(URL := 'file://C:\config.sys');   V.StatusText := V.LocationURL;   Sleep(10000);   V.Quit; end;

Приведенный выше код весьма необычен и заслуживает детального рассмотрения.

  1. Переменная V не является классом и, очевидно, не имеет ни одного из используемых свойств и методов.
  2. Вызываемые свойства и методы нигде не описаны, однако это не влечет за собой ошибки компиляции.
  3. Объект создается не по CLSID, а по информативному имени, функцией CreateOleObject.


Все это непривычно и выглядит довольно странно. На самом деле ничего странного нет. Компилятор Delphi просто запоминает в коде программы строковые описания обращений к серверу автоматизации, а на этапе выполнения передает их его интерфейсу IDispatch, который и производит синтаксический разбор и выполнение. Исправим третью строку функции на:

V.Left1 := (Screen.Width - 600) div 2;

Программа успешно откомпилируется, однако при попытке ее выполнить выдаст сообщение об ошибке, а именно, что метод «Left1» не поддерживается сервером автоматизации.

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

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

 

Внимание! Если COM-сервер находится в другой «комнате», затраты на позднее связывание  по сравнению с затратами на маршалинг вызовов ничтожны малы. Разница в скорости между ранним и поздним связыванием становится ощутимой (в десятки и сотни раз) при нахождении клиентами сервера в одной «комнате», что возможно только для In-Process-сервера при совместимой с клиентом потоковой модели. Для Out-Of-Process-сервера (размещенного в отдельном исполняемом файле) затраты на вызов метода практически равны.

 

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



Содержание раздела