AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Finden aller Klassen zur Laufzeit

Ein Thema von tgvoelker · begonnen am 4. Jul 2012 · letzter Beitrag vom 4. Jul 2012
Antwort Antwort
tgvoelker

Registriert seit: 9. Sep 2002
Ort: Oelsnitz, Vogtland
44 Beiträge
 
Delphi 12 Athens
 
#1

Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 09:09
Ich bin, wie einige andere auch, an die Problemstellung geraten, sämtliche von einer bestimmten Klasse abgeleiteten Klassen ermitteln zu wollen. Bis dahin hatte ich mit Registrierroutinen gearbeitet, die ich dann manuell im Initialization-Abschnitt der jeweiligen Unit aufgerufen hatte - immer wieder dieselben Schritte bei jeder eingebundenen Unit. Aus dem Ansatz, die ganze Sache etwas einfacher zu machen, kam dann die Fragestellung, ob es nicht möglich sei, alle Klassen in einem Programm zu dessen Laufzeit zu enumerieren.

Ein Projekt (Delphi 2009), welches das Konzept zeigt, ist im Anhang.
Angehängte Dateien
Dateityp: zip EnumClasses.zip (308,4 KB, 10x aufgerufen)
Thomas Völker
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 09:20
Das geht über die RTTI aber wesentlich einfacher.

Eine Demo ist bei Delphi dabei, die genau das (und mehr) macht:
http://radstudiodemos.svn.sourceforg.../rtti_browser/
Darüber kannst du auch z.B. die Methoden der Klassen abrufen und welche Parameter die bekommen usw.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
tgvoelker

Registriert seit: 9. Sep 2002
Ort: Oelsnitz, Vogtland
44 Beiträge
 
Delphi 12 Athens
 
#3

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 10:26
Die entsprechenden Funktionen der RTTI sind erst ab D2010 verfügbar.
Thomas Völker
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 12:20
Wobei du auf diese Weise auch immer mit False-Positives rechnen mußt, falls zufällig etwas Anderes der getesteten Struktur entspricht
und wenn mal jemand auf die Idee kommt etwas an den Strukturen zu ändern (in neueren/anderen Delphis oder FreePascal/Lazarus ) ............


Aber ja, im Prinzip könnte man so alles Mögliche finden.
$2B or not $2B
  Mit Zitat antworten Zitat
tgvoelker

Registriert seit: 9. Sep 2002
Ort: Oelsnitz, Vogtland
44 Beiträge
 
Delphi 12 Athens
 
#5

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 12:40
Wobei du auf diese Weise auch immer mit False-Positives rechnen mußt
Die werden wie folgt ausgeschlossen:

1. Prüfung: Zeigt ein ausgerichteter Pointer auf die eigene Adresse+Offset 88?
2. Prüfung: Entspricht der Klassenname beim Offset 32 dem, was der als TObjectClass gecastete Pointer aus (1) als "ClassName" zurückgibt? ==> EAccessError, wenn keine Klasse
3. Prüfung (redundant): über InheritsFrom(TObject).

Wenn die Methodenzeiger für GetClassName und InheritsFrom auf irgendwas zeigen, dann knallt es - ergo: keine Klasse.
Thomas Völker
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 13:18
Wenn jetzt die (hardcore) Funktionen getrennt vom Formular in einer eigenen Unit wären, dann würde ich den Code gerne zu meine Bibliothek hinzufügen.
Andreas
  Mit Zitat antworten Zitat
tgvoelker

Registriert seit: 9. Sep 2002
Ort: Oelsnitz, Vogtland
44 Beiträge
 
Delphi 12 Athens
 
#7

AW: Finden aller Klassen zur Laufzeit

  Alt 4. Jul 2012, 14:38
Code:
  procedure EnumForms;
  var pAddr:Cardinal;
      pPC:^Cardinal;
      pPS:^ShortString;
      pS,pCN:ShortString;
      pClass:TClass;
      pExcept,pB:Boolean;
  Begin
//nächste Zeile bereitet die Listen vor, zu denen später hinzugefügt wird
    SetUpLists;
    pExcept:=False;
    pAddr:=Cardinal(TObject)+vmtSelfPtr;
    while not pExcept do Begin
      try
        pPC:=Pointer(pAddr);
        if pPC^<>(pAddr-vmtSelfPtr) then Begin Inc(pAddr,4);Continue; End;
        pPC:=Pointer(pAddr-vmtSelfPtr+vmtClassName);
        try
          pPS:=Pointer(pPC^);
        except
          pExcept:=True;
          Continue;
        end;
        try
          pS:=pPS^;
          pClass:=Pointer(pAddr-vmtSelfPtr);
          pCN:=pClass.ClassName;
          pB:=pClass.InheritsFrom(TObject);
        except
          Inc(pAddr,4);
          Continue;
        end;
        if (pCN=pS)and(pB) then Begin
//hier prüfe ich auf Forms und füge die zu best. Listen hinzu. Der Part ist also variabel
          if pClass.InheritsFrom(TForm) And (pClass<>TForm) And (pClass<>TReferenceForm) then Begin
            if pClass.InheritsFrom(TReferenceForm) then PRefFormList.Add(pClass.ClassName);
            PFormList.AddObject(pClass.ClassName,TFormListDesc.Create(TFormClass(pClass)));
          End;
//Ende Prüfung
          pAddr:=Cardinal(pPS)+Length(pS)+1;
          if pAddr mod 4>0 Then pAddr:=((pAddr shr 2) shl 2)+4;
        End Else Inc(pAddr,4);
      except
        pExcept:=True;
      end;
    End;
  End;
Thomas Völker
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz