2

我有这个 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 的返回值识别为有效的 Script Class。是否有可能在不回退到使用 OnEval-Eventhandler 手动公开每个方法的情况下做到这一点?

4

1 回答 1

2

ExposeRTTI 目前不支持类类型的参数。

这是因为在脚本中返回一个直接的 Delphi 类可能会产生问题,因为 Delphi 对象的生命周期是任意的和不确定的(Delphi 端的对象可以随时被销毁而无需通知 fi)。

您不必手动公开每个方法,您可以对每个涉及基本类型的方法使用 RTTI 公开器,而只需手动处理涉及类类型的方法。

然后,您必须决定如何公开脚本端对象,以及它们与 Delphi 端对象的关系,这是 RTTI 没有提供的任何线索。

例如,使用您的原始代码,OnEval 代码只会创建一个新的脚本对象,该对象为每个调用包装方法 Result。

但是,如果 Foo 的实现被更改为类似的东西,它的 RTTI 签名仍然会完全相同

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 组件)。

于 2011-04-21T06:54:06.480 回答