给出一个IScriptObj
参考如何获得相应的IInfo
或TProgramInfo
?
我有一个包装Delphi对象的脚本对象.
为了管理脚本对象的生命周期,Delphi对象存储对脚本对象的引用.Script对象是使用TdwsUnit
组件声明的.这是非常标准的,如下所示:
德尔福
type
TDelphiObject = class
private
FScriptObject: IScriptObj;
public
procedure DoSomething;
property ScriptObject: IScriptObj read FScriptObject write FScriptObject;
end;
Run Code Online (Sandbox Code Playgroud)
脚本
type
TScriptObject = class
protected
procedure DoSomething; virtual;
public
constructor Create;
end;
Run Code Online (Sandbox Code Playgroud)
Delphi对象的实例化和Delphi /脚本链接的设置发生在脚本对象构造函数的Delphi实现中.也非常标准:
德尔福
// 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;
Run Code Online (Sandbox Code Playgroud)
理想情况下,我会保存IInfo
引用,而不是IScriptObj
以后IInfo
我需要的所有东西,但从经验来看,似乎该IInfo
对象仅在方法调用的持续时间内有效.
无论如何,问题发生TDelphiObject.DoSomething
在Delphi方面调用之后.
TDelphiObject.DoSomething
意味着在脚本对象上调用相应的虚方法:
德尔福
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;
Run Code Online (Sandbox Code Playgroud)
我已经尝试了很多不同的技术来获得可用IInfo
或TProgramInfo
存储IScriptObj
但是每件事都失败了.那么这样做的正确方法是什么?
问题是我假设我需要一个IInfo
接口来封装对象实例,但显然 DWScript 不能那样工作。我需要的是创建一个指向该实例的临时引用/指针,然后IInfo
在其上创建一个。
这是如何完成的:
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;
Run Code Online (Sandbox Code Playgroud)
它的作用是启用从 Delphi 到脚本的面向对象回调。如果没有这个,就只能从 Delphi 调用全局脚本函数。
FWIW,上面的以下两行:
ProgramInfo.Execution.DataContext_Create(Data, 0, DataContext);
Info := TInfoClassObj.Create(ProgramInfo, FScriptObject.ClassSym, DataContext);
Run Code Online (Sandbox Code Playgroud)
可以替换为调用CreateInfoOnSymbol
(在 dwsInfo 中声明):
CreateInfoOnSymbol(Info, ProgramInfo, FScriptObject.ClassSym, Data, 0);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
407 次 |
最近记录: |