Dynamische Arrays via RTTI lesen und schreiben

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

Dynamische Arrays via RTTI lesen und schreiben

Beitragvon m.fuchs » 14. Mär 2019, 15:19 Dynamische Arrays via RTTI lesen und schreiben

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
m.fuchs
 
Beiträge: 2014
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon pluto » 15. Mär 2019, 20:06 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6872
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon pluto » 15. Mär 2019, 23:32 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6872
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon Socke » 16. Mär 2019, 08:58 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Socke
 
Beiträge: 2580
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon pluto » 16. Mär 2019, 11:57 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6872
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon m.fuchs » 16. Mär 2019, 13:24 Re: Dynamische Arrays via RTTI lesen und schreiben

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 Compilerschlater 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
m.fuchs
 
Beiträge: 2014
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon pluto » 16. Mär 2019, 13:28 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6872
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon Socke » 17. Mär 2019, 12:54 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Socke
 
Beiträge: 2580
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon pluto » 17. Mär 2019, 13:19 Re: Dynamische Arrays via RTTI lesen und schreiben

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
Aktuelles Projekt: PlutoArduino
pluto
 
Beiträge: 6872
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried