打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Delphi

I wrote a scriptlanguage for my applications and my goal is to make it possible to publish any type from delphi in the script. I use rtti to automatize this task. For any instance type like classes I use the following code to find and call a method from script.

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;  

But with a record this code doesn't work, because the TRttiMethod type doesn't offer an Invoke() method for record types. I can access the method infos by Info.GetMethod('AMethod') from the record type.
For example i have a record like this:

TRecordType = record    Field1, Field2 : single;    procedure Calc(Value : integer);   end;  

So does anyone know a way to invoke a method from a record if i have methodname or methodaddress?

asked Apr 17 '12 at 13:48


 
Did you just reinvent DWScript? –  David Heffernan Apr 17 '12 at 13:55

 
Thanks for the hint, but I know DWScript. My language is intended as a scriptable interface to a delphi program where constructs like AObject.AFunction.AObject.DoSomething are possible. –  DragonFlyOfGold Apr 17 '12 at 14:05
2  
I thought DWScript could do all that, but perhaps I'm wrong –  David Heffernan Apr 17 '12 at 14:15

 
Just an answer from Barry Kelly here at SO stating that there is no RTTI for methods on records: Delphi - RTTI info about methods in records. –  LU RD Apr 17 '12 at 14:47
1  
Ok, RTTI for record methods was introduced in XE2. See example TRttiRecordType_(Delphi). –  LU RD Apr 17 '12 at 15:22
show 3 more comments

1 Answer

up vote 7 down vote accepted

After exploring the links in delphi documentations posted in the comments above I took a closer look at the delphi type TRttiRecordMethod in System.Rtti. It provides the method DispatchInvoke() and this method expects a pointer. So following code works:

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; 

If you want to call a static method or overloaded operator the code doesn't work. Delphi internally always add the self pointer to parameterlist, but this will cause a accessviolation. So use this code instead:

  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;    
answered Apr 17 '12 at 16:02


 
Thanks, this really helped me in my quest for a way to dynamically call a SOAP web service! –  dahook Jun 28 '12 at 22:57
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
java反射机制method用法
利用java反射调用类的的私有方法
Java反射中Method类invoke方法的用法
谈谈:程序集加载和反射
Struts学习笔记(一)
C#反射机制
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服