2012-04-17 9 views
7

私は自分のアプリケーションのスクリプト言語を書いていましたが、私の目標はスクリプト内のどのタイプのものもdelphiから公開できるようにすることです。私はこの作業を自動化するためにrttiを使います。クラスのようなインスタンス型の場合は、次のコードを使用してスクリプトからメソッドを見つけて呼び出します。Delphi - 名前ごとにレコードメソッドを呼び出す

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タイプがレコードタイプのための呼び出し()メソッドを提供していないので、このコードは、動作しないレコードを持ちます。レコード型からInfo.GetMethod( 'AMethod')でメソッド情報にアクセスできます。例えば
私はこのような記録を持っている:

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

私はmethodNameのかmethodaddressを持っているのであれば、誰でもレコードからメソッドを呼び出すための方法を知っていますか?

+0

[DWScript](http://code.google.com/p/dwscript/)を再開発しましたか? –

+0

ヒントはありがたいですが、私はDWScriptを知っています。私の言語は、AObject.AFunction.AObject.DoSomethingのような構文が可能なdelphiプログラムへのスクリプト可能なインターフェイスとして意図されています。 – DragonFlyOfGold

+2

私はDWScriptがそれをすべて行うことができると思ったが、おそらく私は間違っていると思う。 –

答えて

12

上記のコメントに掲載されているデルファイ文書のリンクを調べた後、私はSystem.Rttiのdelta型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; 

あなたは、静的メソッドやコードが機能しないオーバーロードされた演算子を呼び出したい場合。デルファイは内部的に常にパラメータリストに自己ポインタを追加しますが、これによりアクセス違反が発生します。したがって、代わりにこのコードを使用してください:

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;  
+0

おかげさまで、これはSOAP Webサービスを動的に呼び出すための私の探求に本当に役立ちました! – dahook

関連する問題