Тип данных Variant

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

uses ComObj;

procedure TForm1.Button1Click(Sender: TObject);

var

V: Variant;

begin

V := Create0le0bject('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(1000);

V.Quit;

End;

В этом примере

· переменная V не обладает ни одним из используемых свойств и методов; вызываемые свойства и методы нигде не описаны, однако это не ведет к ошибке компиляции;

· объект создается не по CLSID, а по информативному имени функцией CreateOleObject. Компилятор Delphi просто запоминает в коде программы строковые описания обращений к серверу автоматизации, а на этапе выполнения передает их интерфейсу IDispatch сервера, который и производит синтаксический анализ и выполнение. Если исправить третью строку процедуры следующим образом

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

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

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

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

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

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