Delphi.Вызов методов объектов по имени.Часть 2
 Использование published-событий

Для published-событий Delphi генерирует полную информацию о декларации метода. Эту информацию IDE использует для генерации заголовка метода при создании события. Мы же воспользуемся этой информацией для определения типов параметров. Приведу сразу код готового класса:

Метод MethodExists просто возвращает true, если у класса C есть published-событие с именем Name.

Инетереснее второй метод Invoke. Он вызывает метод объекта Instance с именем Name. Arguments - список параметров метода, Res - возвращаемый результат.

  Несколько ограничений на вызовы: 

  • Реализованы вызовы только для модели stdcall. Если вызываемый метод использует другую модель, будет сгенерировано исключение.
  • При вызове поддерживается не более 20-ти параметров.
  • Параметры могут передаваться как по значению, так и по ссылке. Разрешено использование только модификатора var (const, out и прочее не поддерживается).
  • В качестве параметров и возвращаемых значений допускаются только следующие типы: Integer, Double, String. Использование других типов вызывает исключение.

Посмотрим как можно использовать класс TRTTI. Пусть есть класс TMyClass, в котором реализован метод _Func5. Обратите внимание, что в конструкторе класса мы связываем этот метод с событием Func5 и именно это наименование используем для вызова метода:

pascal
type
  TFunc5 = function(var A : integer; var D:Double; var S:String) : String stdcall of object;

  // Класс должен быть унаследован от TPersistent 
  // или заключен в директивы (*$M+*) (*$M-*)
  TMyClass = class(TPersistent)
  private
     // Метод, который будем вызывать
     function _Func5(var A:integer; var D:Double; var S:String) : String; stdcall;
  published
     property Func5 : TFunc5 read FFunc5;
  public
     constructor Create;
  end;

// Связывание метода с событием
constructor TMyClass.Create;
begin
   inherited Create;
   FFunc5 := _Func5;
end;

function TMyClass._Func5(var A:integer; var D:Double; var S:String) : String;
begin
   A := 789456;
   D := 123456789;
   S := 'var test string';
   Result := 'TestString';
end;

Создаем эеземпляр этого класса и вызываем метод.

pascal
var Arguments : TVarDataArray;
    res:TVarData;
    A:integer;
    D:Double;
    S, S1:String;
begin
   C := TMyClass.Create;
   try
       // Задание параметров метода
       SetLength(Arguments, 3);
       Variant(Arguments[0]) := 25;
       Variant(Arguments[1]) := 1;
       Variant(Arguments[2]) := 'test string';

       TRTTI.Invoke(C, 'func5', res, Arguments);

       // значения параметров, переданных по ссылке
       A := Variant(Arguments[0]);  // 789456
       D := Variant(Arguments[1]);  // 123456789
       S := Variant(Arguments[2]);  // 'var test string'

       // Результат функции
       S1 := Variant(res);          // 'TestString'
   finally
      C.Free;
   end;
end;

Здесь мы создали массив Arguments и заполнили его нужными параметрами. После вызова TRTTI.Invoke массив Arguments будет содержать измененные значения, т.к. все параметры в нашем методе передаются по ссылке.

 Delphi.Вызов методов объектов по имени.Часть 1


04 июля 2009

No comments
Вы можете оставить комментарий или задать вопрос
Ваше имя:

Текст сообщения:


Copyright © 2009-2014 by