Dynamische Arrays via RTTI lesen und schreiben

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Dynamische Arrays via RTTI lesen und schreiben

Beitrag von m.fuchs »

Hallo,

angenommen ich habe folgende Klasse:

Code: Alles auswählen

type
  TMyClass = class(TObject)
    private
      FData: TBytes;
    published
      property Data: TBytes read FData write FData;
  end;


Wie kann ich per RTTI auf Data zugreifen und den Inhalt lesen und/oder schreiben?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Ich habe das hier gefunden:
https://www.delphipraxis.net/192269-rtt ... ecord.html

Habe es aber nicht getestet...
Ich glaube Array's sind immer ein Problem für die RTTI...

Ich habe aber in der Unit RTTI geschaut und habe mir mal folgendes zusammen gereimt:

Es gibt dort das Record: TValue hat eine "Methode" wie "IsArray"
Dann gibt es dort die Methode "GetArrayLength"
und die zwei Methoden
function GetArrayElement(AIndex: SizeInt): TValue;
procedure SetArrayElement(AIndex: SizeInt; constref AValue: TValue);

Ach ja, deine Klasse muss unbedingt von "TPersistent" abgeleitet werden, ab da Funktioniert die RTTI Erst.
Eine gute Anlaufstelle ist immer der Objekt Inspektor von Lazarus, er nennt sich TTIPropertyGrid ist im Packet rttiControlls(was du nach installieren musst, wenn es nicht schon Installiert ist).

Meine Erfahrungen mit der RTTI liegen schon ein paar Jahren Zurück.

Edit: Data sollte ins published verschoben werden, sonst werden sie nicht gefunden:
http://www.blong.com/conferences/borcon ... /cb140.htm

Eine Bessere Seite, danach baue ich gerade ein Beispiel(Weil ich es auch selbst wissen möchte).
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Diese Seite hat mir geholfen:
https://stackoverflow.com/questions/411 ... s-property

Code: Alles auswählen

 
procedure TForm1.BitBtn1Click(Sender: TObject);
var
  Count, Loop: Integer;
  List: TPropList;
 
  PropInfo:PPropInfo;
  ArrayTypeData:TArrayTypeData;
  TestArray:Pointer;
  i:integer;
 
begin
  MyClass:=TMyClass.Create;
  MyClass.Data:=[10,10,15,10];
  Count := GetPropList(TypeInfo(MyClass), tkAny, @List);
  Listbox1.Items.BeginUpdate;
  for Loop := 0 to Pred(Count) do begin
    PropInfo:=List[Loop];
    if PropIsType(MyClass,PropInfo^.Name,tkDynArray) then begin
      TestArray:=GetDynArrayProp(MyClass,PropInfo);
 
      for i := 0 to high(TBytes(TestArray)) do begin
        ListBox1.Items.Add(intToStr(TBytes(TestArray)[i]));
      end;
    end;
 
 
//    Listbox1.Items.Add(PropInfo^.Name);
  end;
  Listbox1.Items.EndUpdate;
end;
 


So wie es aussieht, scheint es so zu gehen... jedenfalls das Auslesen, kannst es dir mal anschauen, vielleicht können wir das ja noch optimieren und erweitern.
MFG
Michael Springwald

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von Socke »

m.fuchs hat geschrieben:Wie kann ich per RTTI auf Data zugreifen und den Inhalt lesen und/oder schreiben?

Du musst als erstes die Property Data auf published setzen - für public werden keine RTTI-Daten erzeugt.
Für TObject musst du dies noch per Compiler-Schalter aktivieren: {$M+}
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Du musst als erstes die Property Data auf published setzen - für public werden keine RTTI-Daten erzeugt.

Ich meine schon, für Klassen, weil nicht alles geht in "published" z.b. Klassen und ich meine auch Record gehen nicht.

Für TObject musst du dies noch per Compiler-Schalter aktivieren: {$M+}

Ach, dass geht auch ohne das die Klasse von "TPersistent" abgeleitet ist....

Ich hatte zunächst Probleme, darum musste ich "{$define NoGenericMethods}" verwenden innerhalb von der RTTI Unit.
Auszug aus der RTTI Unit, außerdem scheint diese auch noch "experimental" zu sein.:
{ Note: since the Lazarus IDE is not yet capable of correctly handling generic
functions it is best to define a InLazIDE define inside the IDE that disables
the generic code for CodeTools. To do this do this:

- go to Tools -> Codetools Defines Editor
- go to Edit -> Insert Node Below -> Define Recurse
- enter the following values:
Name: InLazIDE
Description: Define InLazIDE everywhere
Variable: InLazIDE
Value from text: 1
}
MFG
Michael Springwald

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von m.fuchs »

Socke hat geschrieben:
m.fuchs hat geschrieben:Wie kann ich per RTTI auf Data zugreifen und den Inhalt lesen und/oder schreiben?

Du musst als erstes die Property Data auf published setzen - für public werden keine RTTI-Daten erzeugt.
Für TObject musst du dies noch per Compiler-Schalter aktivieren: {$M+}

Jepp, das hatte ich im Beispiel leider falsch geschrieben. Die Property ist published und auch der Compilerschalter passt. Für Strings, Integer, etc. bekomme ich auch alles schon hin. Ich weiß bloss nicht wie ich bei einem dynamischen Array die Übergabe mache.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Hilft mein Beispiel nicht? oder habe ich was Falsch verstanden?
Die Funktion die dafür vorgesehen ist heißt "GetDynArrayProp" und gibt ein Pointer zurück, welches du Umwandeln kannst, ist vielleicht das das Problem?
MFG
Michael Springwald

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von Socke »

pluto hat geschrieben:Hilft mein Beispiel nicht? oder habe ich was Falsch verstanden?

Dein Beispiel funktioniert bei mir ganz gut.
Da eine Klasse mehrere Eigenschaften mit unterschiedlichen Array-Typen haben kann, sollte man vor einem harten Typecast den Datentyp prüfen.
Z.B. in der Schleife über die Eigenschaften:

Code: Alles auswählen

if PropInfo^.PropType^.Name <> PTypeInfo(TypeInfo(TBytes))^.Name then continue;


Man kann das ganze Array-Handling auch generisch per RTTI aufbauen, das ist dann ein wenig komplizierter ...
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Man kann das ganze Array-Handling auch generisch per RTTI aufbauen, das ist dann ein wenig komplizierter ...

Ich habe in der RTTI Unit auch das Record TValue gefunden, hast du damit mal gearbeitet? Ich habe dazu kein echtes Beispiel finden können....
MFG
Michael Springwald

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von m.fuchs »

Hm, das Beispiel mit GetDynArrayProp geht wohl nur in Delphi. Die Lazarus-Verseion der Unit typeinfo kennt das nicht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Du musst diese Units einbinden:
Rtti, TypInfo

Ich habe es bei mir unter Linux mit Lazarus kompiliert.
MFG
Michael Springwald

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von m.fuchs »

Meinst du die experimentelle Unit rtti aus dem FPC-Trunk?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Ja, genau. Da stand was von "experimentelle", damit geht es....
MFG
Michael Springwald

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von m.fuchs »

Na ok, dann nützt mir das erstmal nix. Aber ich behalte es im Auge, wenn irgendwann man 3.2. released wird.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Dynamische Arrays via RTTI lesen und schreiben

Beitrag von pluto »

Na ok, dann nützt mir das erstmal nix. Aber ich behalte es im Auge, wenn irgendwann man 3.2. released wird.

Ich habe noch mal was getestet: Die Unit RTTI wird nicht gebraucht.

Die Funktion ist in "TypInfo" erhalten.

Hinweis: Du hattest "typeinfo" geschrieben, ich meine jedoch "TypInfo" also Type ohne e
MFG
Michael Springwald

Antworten