何が起こっているのかを完全には理解していませんが、たとえばIsPublishedProp
ユニットTypInfo
を見ると、インスタンスのClassInfoがTypeInfo構造体へのポインターとしてキャストされていることがわかります。
PTypeInfo(Instance.ClassInfo)
ClassInfoメソッドを見ると、その値がvmtテーブルに関連していると思われる単純なポインターが返されます。
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
vmtTypeInfo
値は-72です。その前の-76の4バイトはvmtInitTable
です。vmtTypeInfoの後には、FieldTable、MethodTable、DynamicTableなどが続きます。
たとえば、vmtInitTable値はで使用され、TypeInfo構造体へのポインターとしてTObject.CleanupInstance
渡されます。_FinalizeRecord
したがって、TypeInfo構造体を指すTypeInfo構造体の前の4バイトは、設計上、vmt構造体の一部であるように見えます。
編集
メイソンが正しく指摘したように、上記は完全な赤いニシンです(コメントを参照)。他の人がそれを追いかける必要がないように、私は答えを残しています。
更新
変数とそのアドレスに関する混乱を避けるために、Masonのテスト手順を次のように書き直しました。
procedure test(info: PTypeInfo);
begin
writeln('value of info : ', cardinal(info));
writeln('info - 4 : ', cardinal(info) - 4);
writeln('value 4 bytes before: ', cardinal(PPointer(cardinal(info)-4)^));
end;
次の情報を使用して呼び出します。
procedure TryRTTIStuff;
begin
writeln('TPersistent');
test(TypeInfo(TPersistent));
writeln('TTypeKind enumeration');
test(TypeInfo(TTypeKind));
writeln('Integer');
test(TypeInfo(Integer));
writeln('Nonsense');
test(PTypeInfo($420000));
end;
最初の3つは、メイソンが説明する結果を生成します。最後のwritelnのポインター値を表示するためにwritelnを追加しただけです。TryRTTIStuffの最後の呼び出しは、有効なTypeInfo構造体へのポインターを渡さない場合、呼び出しの1番目と3番目のwritelnで同じ値を取得しないことを示すことです。
TypeInfoで何が起こっているかについてはまだ手がかりがありません。新しいD2010RTTIの作成者であるBarryKellyに尋ねる必要があるかもしれません。したがって、古いものについても多くのことを知っている必要があります...