DelphiWeb脚本:如何通过RTTI公开一个类,RTTI包含返回另一个(公开的)类的方法

DelphiWeb脚本:如何通过RTTI公开一个类,RTTI包含返回另一个(公开的)类的方法,delphi,rtti,dwscript,Delphi,Rtti,Dwscript,我有这门德尔福课 type TAnotherClass = class end; TMyClass = class function Foo: TAnotherClass; end; function TMyClass.Foo: TAnotherClass; begin Result := TAnotherClass.Create; end; 现在我想通过“dwsRTTIExposer.pas”公开这个类: 我的脚本如下所示: var a: TMyClass =

我有这门德尔福课

type
  TAnotherClass = class
  end;

  TMyClass = class
    function Foo: TAnotherClass;
  end;

function TMyClass.Foo: TAnotherClass;
begin
  Result := TAnotherClass.Create;
end;
现在我想通过“dwsRTTIExposer.pas”公开这个类:

我的脚本如下所示:

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

不幸的是,DelphiWeb脚本无法将TMyClass.Foo的返回值识别为有效的脚本类。有没有可能做到这一点而不返回到使用OnEval Eventhandler手动公开每个方法?

ExposerTI目前不支持类类型的参数

这是因为在脚本中返回一个直接的Delphi类可能会有问题,因为Delphi对象的生命周期是任意的和不确定的(Delphi端对象可以在任何时候销毁,而不通知f.i.)

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

这将使您不得不决定如何公开脚本端对象,以及它们与Delphi端对象的关系,这是RTTI没有提供任何线索的

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

但是,如果将Foo的实现更改为

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组件)之类的事情.

谢谢您的回复。这对我没什么帮助。我自己编写了一个Exposer,它通过TProgramInfo.RegisterExternalObject和IScriptObj.ExternalObject支持类作为参数和结果。它工作起来很有魅力;-)但你是对的,生命周期问题使这不是一个普遍的解决办法。但是可以添加另一个属性来控制“AutoFree”。你对我的解决方案感兴趣吗?@Stebi:我对你的解决方案感兴趣。我需要公开嵌套的实例类,其中的生命周期完全在我的控制之下,我只希望对它们进行只读访问。@BrianFrost你找到答案了吗?我也有同样的问题。
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;