Delphi Web Script: Как представить класс через RTTI, который содержит метод, возвращающий другой (открытый) класс - PullRequest
2 голосов
/ 20 апреля 2011

У меня есть этот класс Delphi

type
  TAnotherClass = class
  end;

  TMyClass = class
    function Foo: TAnotherClass;
  end;

function TMyClass.Foo: TAnotherClass;
begin
  Result := TAnotherClass.Create;
end;

Теперь я хотел бы выставить этот класс через "dwsRTTIExposer.pas":

myUnit.ExposeRTTI(TypeInfo(TMyClass));
myUnit.ExposeRTTI(TypeInfo(TAnotherClass));

Мой скрипт выглядит так:

var a: TMyClass = TMyClass.Create;
var b: TAnotherClass;
b := a.Foo;

К сожалению, Delphi Web Script не распознает возвращаемое значение из TMyClass.Foo как допустимый класс сценариев.Есть ли возможность сделать это, не прибегая к ручному открытию каждого метода с помощью OnEval-Eventhandler?

1 Ответ

2 голосов
/ 21 апреля 2011

ExposeRTTI в настоящее время не поддерживает параметры типа класса.

Это потому, что возврат прямого класса Delphi в сценарии может быть проблематичным, поскольку жизненный цикл объектов Delphi является произвольным и неопределенным (Delphi-объект может быть уничтожен в любое время без уведомления fi).

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

После этого вам придется решать, как вы хотите, чтобы объекты на стороне скрипта отображались, и какова их связь с объектом на стороне Delphi, что является чем-тоRTTI не дает никаких подсказок о.

Например, с вашим исходным кодом, код OnEval просто создаст новый объект сценария, который обернет метод Result для каждого вызова.

Но подпись RTTIFoo был бы точно таким же, если бы его реализация была изменена на что-то вроде

TMyClass = class
   private
      FFoo: TAnotherClass;
   public
      function Foo: TAnotherClass;
end;

function TMyClass.Foo: TAnotherClass;
begin
   if FFoo=nil then
      FFoo := TAnotherClass.Create;
   Result := FFoo;
end;

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

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

...