首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DWScript:从IScriptObj到IInfo或TProgramInfo

DWScript:从IScriptObj到IInfo或TProgramInfo
EN

Stack Overflow用户
提问于 2014-12-16 14:59:30
回答 1查看 437关注 0票数 7

给定IScriptObj引用,如何获得相应的IInfoTProgramInfo

我有一个脚本对象包装了一个Delphi对象。

为了管理脚本对象的生存期,Delphi对象存储对脚本对象的引用。脚本对象是用TdwsUnit组件声明的。这是相当标准的,而且是这样的:

Delphi

代码语言:javascript
复制
type
  TDelphiObject = class
  private
    FScriptObject: IScriptObj;
  public
    procedure DoSomething;
    property ScriptObject: IScriptObj read FScriptObject write FScriptObject;
  end;

脚本

代码语言:javascript
复制
type
  TScriptObject = class
  protected
    procedure DoSomething; virtual;
  public
    constructor Create;
  end;

Delphi对象的实例化和Delphi/script链接的设置发生在script对象构造函数的Delphi实现中。同样非常标准的:

Delphi

代码语言:javascript
复制
// Implements TScriptObject.Create
procedure TMyForm.dwsUnitClassesTScriptObjectConstructorsCreateEval(Info: TProgramInfo; var ExtObject: TObject);
var
  DelphiObject: TDelphiObject;
  DelphiObjectInfo: IInfo;
begin
  // Create the Delphi-side object
  DelphiObject := TDelphiObject.Create;

  // Get the script object "self" value
  DelphiObjectInfo := Info.Vars['self'];

  // Store the ScriptObject reference
  DelphiObject.ScriptObject := DelphiObjectInfo.ScriptObj;

  // Return the instance reference to the script
  ExtObject := DelphiObject;
end;

理想情况下,我应该保存IInfo引用,而不是IScriptObj,因为IInfo完成了以后所需的一切,但是从经验来看,IInfo对象只在方法调用的持续时间内有效。

无论如何,当在Delphi端调用TDelphiObject.DoSomething时,这个问题会在稍后发生。TDelphiObject.DoSomething用于调用脚本对象上相应的虚拟方法:

Delphi

代码语言:javascript
复制
procedure TDelphiObject.DoSomething;
var
  Info: IInfo;
  DoSomethingInfo: IInfo;
begin
  // I have a IScriptObj but I need a IInfo...
  Info := { what happens here? };

  // Call the virtual DoSomething method
  DoSomethingInfo := Info.Method['DoSomething'];
  DoSomethingInfo.Call([]);
end;

为了从存储的IInfoTProgramInfo中获得可用的IScriptObj,我尝试了许多不同的技术,但是每件事都失败了。那么,正确的做法是什么呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-21 18:37:50

问题是,我假设我需要一个IInfo接口来封装对象实例,但显然DWScript不是这样工作的。我需要的是创建一个对实例的临时引用/指针,然后在上面创建一个IInfo

这是如何做到的:

代码语言:javascript
复制
procedure TDelphiObject.DoSomething;
var
  ProgramExecution: TdwsProgramExecution;
  ProgramInfo: TProgramInfo;
  Data: TData;
  DataContext: IDataContext;
  Info: IInfo;
  DoSomethingInfo: IInfo;
begin
  (*
  ** Create an IInfo that lets me access the object represented by the IScriptObj pointer.
  *)

  // FProgramExecution is the IdwsProgramExecution reference that is returned by
  // TdwsMainProgram.CreateNewExecution and BeginNewExecution. I have stored this
  // elsewhere.
  ProgramExecution := TdwsProgramExecution(FProgramExecution);
  ProgramInfo := ProgramExecution.AcquireProgramInfo(nil);
  try
    // Create a temporary reference object
    SetLength(Data, 1);
    Data[0] := FScriptObject;
    ProgramInfo.Execution.DataContext_Create(Data, 0, DataContext);
    // Wrap the reference
    Info := TInfoClassObj.Create(ProgramInfo, FScriptObject.ClassSym, DataContext);


    // Call the virtual DoSomething method
    DoSomethingInfo := Info.Method['DoSomething'];
    DoSomethingInfo.Call([]);

  finally
    ProgramExecution.ReleaseProgramInfo(ProgramInfo);
  end;
end;

这样做是启用从Delphi到脚本的面向对象的回调。没有这一点,就只能从Delphi调用全局脚本函数。

FWIW,上述两行:

代码语言:javascript
复制
ProgramInfo.Execution.DataContext_Create(Data, 0, DataContext);
Info := TInfoClassObj.Create(ProgramInfo, FScriptObject.ClassSym, DataContext);

可以用对CreateInfoOnSymbol的调用(在dwsInfo中声明)代替:

代码语言:javascript
复制
CreateInfoOnSymbol(Info, ProgramInfo, FScriptObject.ClassSym, Data, 0);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27507501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档