从DWScript调用类的一个过程

3
我该怎样从主窗体中创建的类中调用一个过程呢?可以按照这个伪代码来完成吗?
type
  TDemo = class
    procedure test;
    constructor Create;
    destructor Destroy; override;
  end;

var
  Form28: TForm28;
  Demo:TDemo;

implementation

{$R *.dfm}

procedure TForm28.Button1Click(Sender: TObject);
var
   prog : IdwsProgram;
   exec : IdwsProgramExecution;
begin
   Demo := TDemo.Create;
   prog := DelphiWebScript1.Compile('Demo.Test;');
   exec := prog.Execute;
end;
2个回答

2

有一个有限的RTTI exposer和RTTI connector,允许通过RTTI访问Delphi类。

然而,这些RTTI工具并没有被广泛使用,因为大多数的Delphi类对于脚本使用来说是不安全的。我的意思是,很容易使主机崩溃或泄漏内存,因此“原始”的Delphi类通常不适合于最终用户脚本编写(即最终用户将无法容忍错误,您也无法提供稳定的调试等)。

一种替代手动暴露和加强TdwUnit事件处理程序中所暴露的类的方法是将您的类作为OLE Automation对象公开,然后您可以使用DWScript COM连接器来访问它们。优点在于,要公开自动化对象,您通常必须进行至少最小程度的增强以防止内存泄漏和悬空指针,并且您的自动化类将可从其他支持COM的环境中访问。

关于RTTI出现问题的例子,请考虑完全自动管理的VCL类,例如TComponent或TCollection,如果您只有原始的RTTI暴露,那么执行以下操作的脚本可能会出现问题:

item := myCollection.Add;
myCollection.Clear;
item.Caption := 'hello bug';

如果不加任何安全方式通知脚本用户潜在错误,将导致主机应用程序的随机内存覆盖。

即将推出的Delphi ARC编译器可能会为某些类提供减轻内存覆盖的方法(尽管不是所有类,因为ARC目前实现/规避TComponent等)。此外,由于各种原因(最突出的原因是我目前没有访问权限),Delphi ARC编译器目前不受支持。


据我所知,paxcompiler 可以做到这一点。我想知道为什么 DWScript 不能做到。 - user1647411
Pax编译器不提供沙盒化或封装,Pax脚本中的错误可能会导致主机崩溃,并且也无法提供稳定的调试功能。DWScript是围绕着能够沙盒执行脚本、随时中止任何脚本而无内存泄漏,并通常可以处理有缺陷的脚本(以便在主机应用程序中进行调试)而构建的。 - Eric Grange

1
要做到这一点,首先必须将您的本地类暴露给脚本引擎。请查看TdwsUnit组件。它声明了一个与外部代码交互的脚本单元。您可以在表单上拖放一个组件,定义类、定义其方法,并在OnEval事件上挂接调用外部例程的事件处理程序。

1
是的,但如果我有200个方法怎么办? 我必须手动添加所有这些吗?我的意思是必须有一种简单的方法与“外部”世界通信。这是否可以通过RTTI完成? - user1647411
目前来看,如果您希望脚本引擎能够与类进行交互,那是的。这是DWS的一个较为困难的问题;它被设计为更多的是一个自包含的脚本系统(用于构建网页,因此得名),而不是像一些脚本系统一样在强大的独立代码库之上构建自动化层。我已经与Eric合作开发了一些额外的功能,使这种事情变得更加容易,但目前还没有准备好。我知道存在一些基于RTTI的接口,但我不熟悉它的工作原理,并且我确实知道,如果您使用它,就会失去静态类型检查。 - Mason Wheeler
那太糟糕了...非常非常糟糕。不幸的是,这是一个停机点。 - user1647411
@EricSantos:我知道。这就是为什么我正在努力工作的原因。:) - Mason Wheeler
有没有可以做到这个的脚本引擎? - user1647411

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接