我需要获取任何单元的名称(命名空间)TRttiType http://docwiki.embarcadero.com/CodeSamples/en/Category%3aRtti.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;
2)解析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;
问题是,存在另一种可靠的方法来获取任何单位的名称TRttiType
?
信息就在那里,但解析限定名称是目前获取它的最佳方法。
如果你想以困难的方式做到这一点,你可以:
在 system.pas 单元中你有一个变量LibModuleList: PLibModule = nil;
其中包含
已加载模块的列表。这是指向原始 RTTI 信息的指针,可以在没有 RTTI.pas 的情况下使用。您可以迭代所有原始信息来确定单位名称。
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 的原始方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)