不完全理解发生了什么,但是当您查看单元中的示例IsPublishedProp
时TypInfo
,您会看到它将实例的 ClassInfo 转换为指向 TypeInfo 结构的指针:
PTypeInfo(Instance.ClassInfo)
当您查看 ClassInfo 方法时,它返回一个简单的指针,其值似乎与 vmt 表相关:
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
vmtTypeInfo
值为 -72。在 -76 之前的四个字节是vmtInitTable
. vmtTypeInfo 之后是 FieldTable、MethodTable、DynamicTable 等。
vmtInitTable 值用于例如TObject.CleanupInstance
并_FinalizeRecord
作为指向 TypeInfo 结构的指针传递给。
因此,指向 TypeInfo 结构的 TypeInfo 结构之前的四个字节似乎是设计使然,并且是 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;
前三个产生了梅森描述的结果。我只添加了一个额外的 writeln 来显示最后一个 writeln 的指针值。TryRTTIStuff 中的最后一个调用是为了表明,当您不传递指向有效 TypeInfo 结构的指针时,您不会在调用的第一个和第三个 writeln 上获得相同的值。
尚不知道 TypeInfo 发生了什么。也许我们应该问巴里凯利,因为他是新 D2010 RTTI 的作者,所以也应该对旧的有很多了解......