我为我的应用程序编写了一种脚本语言,我的目标是能够在脚本中发布来自 delphi 的任何类型。我使用 rtti 来自动执行此任务。对于任何实例类型(例如类),我使用以下代码从脚本查找并调用方法。
var Info : TRttiType;
Meth : TRttiMethod;
Param : TArray<TValue>;
Result : TValue;
AnyClass : TClass;
begin
...
Info := RttiContext.GetType(AnyClass);
Meth := Info.GetMethod('AMethod');
Setlength(Param, 1);
Param[0] := TValue.From<Integer>(11);
Result := Meth.Invoke(ClassInstance, Param);
...
end;
但对于记录,此代码不起作用,因为 TRttiMethod 类型不提供记录类型的 Invoke() 方法。我可以通过 Info.GetMethod('AMethod') 从记录类型访问方法信息。
例如我有这样的记录:
TRecordType = record
Field1, Field2 : single;
procedure Calc(Value : integer);
end;
那么,如果我有方法名称或方法地址,有人知道如何从记录中调用方法吗?
在探索了上面评论中发布的 delphi 文档中的链接之后,我仔细研究了 System.Rtti 中的 delphi 类型 TRttiRecordMethod。它提供了 DispatchInvoke() 方法,并且该方法需要一个指针。
所以下面的代码有效:
TRecordType = record
Field1, Field2 : single;
procedure Calc(Value : integer);
end;
Meth : TRttiMethod;
Para : TRttiParameter;
Param : TArray<TValue>;
ARec : TRecordType;
begin
Info := RttiContext.GetType(TypeInfo(TRecordType));
Meth := Info.GetMethod('Calc');
Setlength(Param, 1);
Param[0] := TValue.From<Integer>(12);
Meth.Invoke(TValue.From<Pointer>(@ARec), Param);
end;
如果您想调用静态方法或重载运算符,则代码不起作用。 Delphi内部总是将self指针添加到参数列表中,但这会导致访问冲突。因此,请改用以下代码:
Meth : TRttiMethod;
Para : TRttiParameter;
Param : TArray<TValue>;
ARec : TRecordType;
begin
Info := RttiContext.GetType(TypeInfo(TRecordType));
Meth := Info.GetMethod('&op_Addition');
...
Meth.Invoke(TValue.From<Pointer>(@ARec), Param);
Result := System.Rtti.Invoke(Meth.CodeAddress, Param, Meth.CallingConvention, Meth.ReturnType.Handle, Meth.IsStatic);
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)