gpt4 book ai didi

delphi - DWScript:如何从 Delphi 端读取元类参数

转载 作者:行者123 更新时间:2023-12-03 15:56:24 27 4
gpt4 key购买 nike

我在 DWScript 中使用元类时遇到问题。

我们正在使用脚本来使 VAR 和最终用户能够自定义我们的应用程序。

我们的应用程序数据基本上由树结构中的许多小对象组成。每个对象可以是“哑的”,因为它只显示数据,也可以在某种程度上是智能的。通过将不同的脚本类与树对象相关联,通过脚本实现智能。

我遇到的问题是脚本需要与 Delphi 端框架通信,它应该使用什么脚本类来实现对象。基本上,我需要将脚本元类传递到 Delphi 端,并以可以安全持久的格式存储信息(按类型名称,可能作为字符串)。我还需要能够走另一条路; IE。从 Delphi 端将元类返回到脚本。

TdwsUnit 声明

type
// Base class of all tree objects
TItem = class
...
end;


// The meta class
// This is actually declared in code since TdwsUnit doesn't have design time support for meta classes.
// Shown here for readability.
TItemClass = class of TItem;


// The procedure that passes the meta class to the Delphi side.
// I cannot use a TItemClass parameter as that isn't declared until run time (after the TdwsUnit has initialized its tables).
procedure RegisterItemClass(AClass: TClass);

脚本

type
TMyItem = class(TItem)
...
end;

begin
// Pass the meta class to the Delphi side.
// The Delphi side will use this to create a script object of the specified type
// and attach it to the Delphi side object.

RegisterItemClass(TMyItem);
end;

德尔福实现

元类的声明,TItemClass。在 TdwsUnit.OnAfterInitUnitTable 中完成。

procedure TMyDataModule.dwsUnitMyClassesAfterInitUnitTable(Sender: TObject);
var
ItemClass: TClassSymbol;
MetaClass: TClassOfSymbol;
begin
// Find the base class symbol
ItemClass := dwsUnitMyClasses.Table.FindTypeLocal('TItem') as TClassSymbol;
// Create a meta class symbol
MetaClass := TClassOfSymbol.Create('TItemClass', ItemClass);
dwsUnitMyClasses.Table.AddSymbol(MetaClass);
end;

RegisterItemClass 实现

procedure TMyDataModule.dwsUnitMyClassesFunctionsRegisterItemClassEval(info: TProgramInfo);
var
ItemClassSymbol: TSymbol;
ItemClassName: string;
begin
ItemClassSymbol := TSymbol(Info.Params[0].ValueAsInteger);
ItemClassName := ItemClassSymbol.Name;
...
end;

所以问题是如何从元类参数获取 TSymbol?
编辑:我在这个old question中找到了部分问题的答案。 .
简而言之,解决方案是将参数值转换为 TSymbol:

但是...

现在假设我将类名存储为字符串。如何从这个类名返回到符号?我需要这个,因为就像脚本可以设置项目类(使用上面的代码)一样,脚本也可以请求项目类。

我尝试使用四种不同的方法中的任何一种来查找符号表,这些方法似乎可以满足我的需要,但它们都找不到该符号。

var
ItemClassName: string;
ItemClassSymbol: TSymbol;
...
ItemClassName := 'TMyItem';
...
ItemClassSymbol := Info.Table.FindTypeSymbol(ItemClassName, cvMagic);
if (ItemClassSymbol = nil) then
ItemClassSymbol := Info.Table.FindSymbol(ItemClassName, cvMagic);
if (ItemClassSymbol = nil) then
ItemClassSymbol := Info.Table.FindTypeLocal(ItemClassName);
if (ItemClassSymbol = nil) then
ItemClassSymbol := Info.Table.FindLocal(ItemClassName);

// ItemClassSymbol is nil at this point :-(

所以问题是给定脚本中声明的元类的名称,如何从Delphi端获取相应的TSymbol?

编辑:我现在找到了最后一部分的一个可能的解决方案。

以下似乎可行,但我不确定这是否是正确的方法。我本以为我需要将符号搜索的范围限制到当前脚本单元。

var
ItemClassName: string;
ItemClassSymbol: TSymbol;
...
ItemClassName := 'TMyItem';
...
ItemClassSymbol := Info.Execution.Prog.RootTable.FindSymbol(ItemClassName, cvMagic);
if (ItemClassSymbol = nil) then
raise EScriptException.CreateFmt('ItemClass not found: %s', [ItemClassName]);

Info.ResultAsInteger := Int64(ItemClassSymbol);

最佳答案

除非我误解了,否则您可能不应该查找最后一部分的符号表,而是在 dwsUnitMyClassesFunctionsRegisterItemClassEval 中维护已注册项目类的表。

其背后的基本原理可能是用户可以在两个不同的上下文中拥有两个“TMyItem”符号,但只注册了一个。注册的符号就是您想要的符号,而且我认为没有一种可靠的方法来找出相关符号(因为重要的上下文不是您尝试将字符串解析回的符号)一个符号,但是符号和字符串关联的符号,即它注册的位置)

关于delphi - DWScript:如何从 Delphi 端读取元类参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23084684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com