Vibeeshan Mahadeva
Vibeeshan Mahadeva

Reputation: 7238

Getting the whole list of classes and objects defined in a unit using RTTI

  1. I want to get the whole list of classes defined in a specific unit
  2. How can I get the list of all instances of those classes, irrespective of where they are created?

Upvotes: 4

Views: 3880

Answers (2)

David Heffernan
David Heffernan

Reputation: 612954

Question 1

The following code does what you ask, relying on the new RTTI introduced in Delphi 2010:

program FindClassesDeclaredInUnit;

{$APPTYPE CONSOLE}

uses
  SysUtils, Rtti, MyTestUnit in 'MyTestUnit.pas';

procedure ListClassesDeclaredInNamedUnit(const UnitName: string);
var
  Context: TRttiContext;
  t: TRttiType;
  DeclaringUnitName: string;
begin
  Context := TRttiContext.Create;
  for t in Context.GetTypes do
    if t.IsInstance then
    begin
      DeclaringUnitName := t.AsInstance.DeclaringUnitName;
      if SameText(DeclaringUnitName, UnitName) then
        Writeln(t.ToString, ' ', DeclaringUnitName);
    end;
end;

begin
  ListClassesDeclaredInNamedUnit('MyTestUnit');
  Readln;
end.


unit MyTestUnit;

interface

type
  TClass1 = class
  end;

  TClass2 = class
  end;

implementation

procedure StopLinkerStrippingTheseClasses;
begin
  TClass1.Create.Free;
  TClass2.Create.Free;
end;

initialization
  StopLinkerStrippingTheseClasses;

end.

Question 2

There is no global registry of object instances.

Upvotes: 3

RRUZ
RRUZ

Reputation: 136391

First before to answer your question, remember always include your delphi version in questions related to the Rtti.

1) Asumming which you are using a new version of delphi (>=2010) you can get the unit name of a type using the QualifiedName property , from there you must check the IsInstance property to determine if is a class.

Check the next sample.

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Rtti,
  System.SysUtils;

procedure Test;
Var
 t : TRttiType;
  //extract the unit name from the  QualifiedName property
  function GetUnitName(lType: TRttiType): string;
  begin
    Result := StringReplace(lType.QualifiedName, '.' + lType.Name, '',[rfReplaceAll])
  end;

begin
 //list all the types of the System.SysUtils unit
  for t in TRttiContext.Create.GetTypes do
   if SameText('System.SysUtils',GetUnitName(t)) and (t.IsInstance) then
     Writeln(t.Name);
end;

begin
  try
    Test;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

2) The Rtti can't list the instances of the classes. because the Rtti is about type information and not of instances.

Upvotes: 5

Related Questions