2009-08-24 21 views
1

私はデータのリストを表示できるはずのコントロールを作成しています。私がしたかったのは、CurrentプロパティとMoveNextメソッドを含むパブリックGetEnumerator関数をチェックするという点でfor-inコンストラクトを模倣することでした。任意の型でGetEnumeratorを呼び出す方法は?

私は次のことを決定しました:

  1. 私は単に私のオブジェクトにMethodAddressを呼び出すことにより、方法のexistanceを確認することができます。アドレスを取得した場合、メソッドが存在します。
  2. RTTIを使用してメソッドの戻り値の型をチェックできます。
  3. RTTIを使用して、プロパティをチェックして読み込むことができます。イン間

しかし、私は情報の小さなビットをしないのです:

  1. はどのようにして、そのアドレス指定された、メソッドを呼び出していますか?私はちょうど定義を書いていますか(私は輸入品のようです)、アドレスをキャストして呼び出しますか?
  2. メソッドの戻り値の型を調べるには、そのPTypeInfoでGetTypeDataを呼び出す必要があります。 PTypeInfoはTypeでTypeInfoを呼び出して取得します。だから、そのメソッドのPTypeInfoを取得するには、そのアドレスだけを与えますか?
+0

私はあなたが達成しようとしていることを本当に理解していません。コントロールはデータを表示しますが、列挙子はどこで再生されますか? – jpfollenius

+0

そして、コントロールに渡されるすべてのデータがIEnumerableを実装していることを確認してみませんか?列挙子に追加の機能を追加しますか?それは何ですか? – jpfollenius

+1

計画は、リストの要素を一覧表示することです。また、私は主にこれを多くの既存のコードと組み合わせて使用​​しますが、そのほとんどはGetEnumeratorを実装してfor-inサポートを有効にしますが、IEnumerableを実装していないもの(Delphiのfor-in構文)。 –

答えて

2
  1. は、メソッドを呼び出すには、あなたが取ります返されたアドレスを取得し、TMethodのコードポインタに置きます。オブジェクトをデータポインタに置き、正しいシグネチャを持つメソッドポインタにキャストします。
  2. 関数のシグネチャを分析するには、かなり複雑なRTTIが必要です。詳細については、http://hallvards.blogspot.com/2006/05/hack-10-getting-parameters-of.htmlを参照してください。

なお、この唯一の作品 インスタンス(またはそのコンポーネントの1つ) も公表性質を持っている場合に発表された方法に ポイント:しかし、底部に向かっ警告に注意してください。 良いニュースは、これが の既存の公開されたメソッドの場合です - をTForm インスタンスのイベントハンドラと同じです。悪いことに、この は、実行中に 公開メソッド( )を動的に呼び出すことはできません(従って、 はイベントに割り当てられません)。

あなたのやっていることは、現在のRTTIモデルでは不可能かもしれません。しかし、Delphi 2010ではRTTIシステムが拡張されていて、これをもっと簡単にやり遂げることができるようになっています.RSNが予定されています。 (Embarcaderoのサイトには、今夜真夜中に向かってカウントダウンしていたリリースカウントダウンがありました。彼らはそれを取り下げてしまったので、まだ公式のリリース日であるかどうかは分かりません)

+0

ええ、あなたの答えは、私が働いていた(編集する前の)Smasherの答えの変種です。そして、あなたは絶対に正しいです - 私はDelphi 2010が出てくるまで運がないです。残念ながら、それは私にとっては遅すぎることが保証されています。 私はあなたの答えを受け入れていますが、私は匿名の方法を含む回避策を使用するつもりです。私がそれを働かせたら、ここに示します。 –

1

最初に、RTTIは公開されたプロパティとメソッドでのみ使用できることに注意してください。

MethodAdressによって取得メソッドを呼び出すには、単に実行します。

TMyMethod = procedure (Self : TObject; const Param : String); 
... 
var 
    MyMethod : TMyMethod; 
... 
MyMethod := Obj.MethodAdress ('MethodName'); 
if Assigned (MyMethod) then 
    MyMethod (Obj, 'Hallo'); 

あなたの2番目の質問については、これは役立つかもしれない:

Link

+1

クール、私はこれをbashにします。私はMethodAddressがPointerを返し、それがコードのみのポインタであると想定していました。それでは、データポインタが利用可能であるため、TMethodとの代入互換性はありますか(あなたの例ではObj)? –

+0

申し訳ありませんが、私は何かを逃しました。答えを編集しました。 – jpfollenius

関連する問題