代码之家  ›  专栏  ›  技术社区  ›  RRUZ

获取属于任何类型的单元名称(TRttiType)

  •  6
  • RRUZ  · 技术社区  · 14 年前

    我需要得到任何 TRttiType .

    到目前为止,我已经尝试了以下方法。

    1) 使用 PTypeData.UnitName ,此解决方案有效,但仅当TTypeKind为tkClass时有效。

    procedure ListAllUnits;
    var
      ctx  : TRttiContext;
      lType: TRttiType;
      Units: TStrings;
    begin
      Units:=TStringList.Create;
      try
        ctx := TRttiContext.Create;
        for lType in ctx.GetTypes do
         if lType.IsInstance then //only works for classes
          if Units.IndexOf(UTF8ToString(GetTypeData(lType.Handle).UnitName))<0 then
          Units.Add(UTF8ToString(GetTypeData(lType.Handle).UnitName));
      Writeln(Units.Text);
      finally
        Units.Free;
      end;
    end;
    

    QualifiedName 属性,这个解决方案到现在还可以,但我不太满意。

    procedure ListAllUnits2;
    
      function GetUnitName(lType: TRttiType): string;
      begin
        Result := StringReplace(lType.QualifiedName, '.' + lType.Name, '',[rfReplaceAll])
      end;
    
    var
      ctx: TRttiContext;
      lType: TRttiType;
      Units: TStrings;
    begin
      Units := TStringList.Create;
      try
        ctx := TRttiContext.Create;
        for lType in ctx.GetTypes do
          if Units.IndexOf(GetUnitName(lType)) < 0 then
            Units.Add(GetUnitName(lType));
        Writeln(Units.Text);
      finally
        Units.Free;
      end;
    end;
    

    trtti类型 ?

    2 回复  |  直到 13 年前
        1
  •  5
  •   Mason Wheeler    14 年前

        2
  •  5
  •   Robert Love    14 年前

    信息就在那里,但解析限定名是目前获取它的最佳方法。

    如果你想用一种很难做到的方法,你可以:

    在系统.pas你有一个变量 LibModuleList: PLibModule = nil; 包含

    TLibModule的关键值是:

      PLibModule = ^TLibModule;
      TLibModule = record
        Next: PLibModule;  { Linked List of Loaded Modules)
        Instance: LongWord;
        ...
        TypeInfo: PPackageTypeInfo; { List of contained Package Information }
        ...
      end;
    

    TypeInfo: PPackageTypeInfo; 你可以进入

      PPackageTypeInfo = ^TPackageTypeInfo;
      TPackageTypeInfo = record
        TypeCount: Integer;
        TypeTable: PTypeTable;
        UnitCount: Integer;
        UnitNames: PShortString; { concatenation of Pascal strings, 
                                   one for each unit }
      end;
    

    然后是TypeTable,它包含要获取PTypeInfo的信息。

      TTypeTable = array[0..MaxInt div SizeOf(Pointer) - 1] of Pointer;
      PTypeTable = ^TTypeTable;
    

    所有这些工作原理的一个例子可以在Rtti.pas公司 TPackage.MakeTypeLookupTable 是关键的方法。此方法还显示QualifiedName始终包含UnitName。因此,可以依赖于解析QualfiedName的原始方法。