Non capisco tutto quello che sta succedendo, ma quando si ha uno sguardo ad esempio IsPublishedProp
nell'unità TypInfo
, si vedere che proietta l'ClassInfo dell'istanza come un puntatore ad una struttura TypeInfo:
PTypeInfo(Instance.ClassInfo)
Quando si guarda il metodo ClassInfo, restituisce un semplice puntatore il cui valore sembra legato al tavolo VMT:
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
vmtTypeInfo
ha un valore di -72. Quattro byte prima di quello a -76 è vmtInitTable
. vmtTypeInfo è seguito da FieldTable, MethodTable, DynamicTable ecc
il valore vmtInitTable viene utilizzato per esempio TObject.CleanupInstance
e passato al _FinalizeRecord
come puntatore alla struttura TypeInfo.
Quindi i quattro byte prima della struttura TypeInfo che punta alla struttura TypeInfo sembrano essere lì per progettazione e parte della struttura vmt.
Modifica
Come Mason ha giustamente sottolineato quanto sopra è una falsa pista completa (vedi commenti). Lascio la risposta in modo che gli altri non debbano inseguirla.
Aggiornamento Per evitare confusione su variabili ed i loro indirizzi, ho riscritto procedura di prova di Mason come segue:
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;
e chiamarlo con le seguenti informazioni:
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;
La prima tre producono i risultati descritti da Mason. Ho aggiunto solo un writeln aggiuntivo per mostrare il valore del puntatore per l'ultimo writeln. L'ultima chiamata in TryRTTistuff mostra che quando non si passa un puntatore a una struttura TypeInfo valida, non si ottiene lo stesso valore sul primo e sul terzo writeln della chiamata.
Nessun indizio su cosa sta succedendo con TypeInfo. Forse dovremmo chiedere a Barry Kelly che è l'autore del nuovo D2010 RTTI quindi dovrei sapere molto anche su quello vecchio ...
Immagino che manchi un 'var' nel codice sopra ... –
@Andreas: Dove? Non vedo alcun vars mancante ... –
Oops! OK, risolto ora. –