从TypInfo.pas中这段代码看起来,PTypeData是从TTypeInfo中读取的。function GetTypeData(TypeInfo: PTypeInfo): PTypeData; assembler;
asm
        { ->    EAX Pointer to type info }
        { <-    EAX Pointer to type data }
        {       it's really just to skip the kind and the name  }
        XOR     EDX,EDX
        MOV     DL,[EAX].TTypeInfo.Name.Byte[0]
        LEA     EAX,[EAX].TTypeInfo.Name[EDX+1]
end;可是TTypeInfo中TypeData的定义已经注释掉了。 TTypeInfo = record        // TTypeInfo 是 RTTI 信息的结构 
   Kind: TTypeKind;        // RTTI 信息的数据类型 
   Name: ShortString;      // 数据类型的名称 
  {TypeData: TTypeData}    // RTTI 的内容 
 end; 请问这是怎么回事?

解决方案 »

  1.   

    TTypeData是变长数据,GetTypeData获取了一个访问指针,实际使用起来类似于var pti: PTypeInfo;
    pti := GetMem(SizeOf(TTypeInfo) + SizeOf(变长数据类型));
    当然上述变长数据类型结构是兼容TTypeData的,这么做是为了节省内存。
      

  2.   

    to pathletboy:
        变长数据为什么要注释掉?
      

  3.   

    program Project1;
    {$APPTYPE CONSOLE}
    uses
      SysUtils;type
    PTypeInfo = ^TTypeInfo;
    TTypeInfo = packed record
    Kind: Byte;
    {TypeData: TTypeData}
    end;
    PTypeData = ^TTypeData;
    TTypeData = packed record
    case Kind: Byte of
    0: (b: Byte);
    1: (w: Word);
    2: (i: Integer);
    end;  TTypeInfoData = packed record
    Kind: Byte;
    TypeData: TTypeData;
    end;
    function getTypeData(const pti: PTypeInfo): PTypeData;
    begin
    Result := Pointer(Cardinal(@pti^.Kind) + 1);
    end;var
      pti: PTypeInfo;
      ptd: PTypeData;
    begin
    writeln(format('SizeOf TTypeInfo: %d', [SizeOf(TTypeInfo)]));
    writeln(format('SizeOf TTypeData: %d', [SizeOf(TTypeData)]));
      writeln(format('SizeOf TTypeInfoData: %d', [SizeOf(TTypeInfoData)]));  GetMem(pti, SizeOf(TTypeInfo) + 1); //TypeData is Byte
      pti^.Kind := 0;
      ptd := getTypeData(pti);
      ptd^.b := 100;
      writeln(format('TypeData: %d', [ptd^.b]));
      FreeMem(pti);  GetMem(pti, SizeOf(TTypeInfo) + 2); //TypeData is Word
      pti^.Kind := 1;
      ptd := getTypeData(pti);
      ptd^.w := 10000;
      writeln(format('TypeData: %d', [ptd^.w]));
      FreeMem(pti);  GetMem(pti, SizeOf(TTypeInfo) + 4); //TypeData is Integer
      pti^.Kind := 2;
      ptd := getTypeData(pti);
      ptd^.i := 1000000;
      writeln(format('TypeData: %d', [ptd^.i]));
      FreeMem(pti);  Readln;
    end.另存为Project1.dpr编译了后运行,看懂这段你的问题就解决了。
      

  4.   

    pathletboy:
    非常感谢你的帮助,你上面的例子我看懂了。
    在vcl中源码中没有看到GetMem,是在其他地方吗,还是编译器分配好了?
      

  5.   

    pathleboy: 
    非常感谢你的回答! :)