![]() |
Pointer of Dynamic Array
Hallo zusammen,
bei der lkJSON-Klasse gibt es eine ForEach-Methode um eine Array eines JSON-Objekts auszulesen. Als Argument muss man die CallBack-Funktion angeben und irgendeine Datenstruktur (in meinem Fall ein dynamisches Array). Folgender Code:
Delphi-Quellcode:
Jetzt ist mein Problem, dass die Länge von dem Array nicht wächst, sonder imm bei 1 bleibt. Also das
type
TElement = record Value: String; end; TElements = array of TElement; PElements = ^TElements; procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; ADataPtr: Pointer; var Continue: Boolean); var Elements: PElements; begin Elements:= PElements(ADataPtr); SetLength(Elements^,High(Elements^)+2); Elements^[High(Elements^)].Value:= xxxx; showmessage(inttostr(High(Elements^))); end; // Aufruf: var MyElements: TElements; (AJSON.Field['su'] as TlkJSONlist).ForEach(ExtractElements, @MyElements);
Delphi-Quellcode:
gibt mir immer 0 zurück (was dann Count=1 bedeutet).
showmessage
Warum? Viele Grüße Croco |
AW: Pointer of Dynamic Array
Hast du mal testhabler eine Stringlist übergeben?
Delphi-Quellcode:
procedure ExtractElements(AElementName: string; AElement: TlkJSONbase;
ElementList: TStringList; var Continue: Boolean); begin ElementList.Add(..); end; (AJSON.Field['su'] as TlkJSONlist).ForEach(@ExtractElements, MyElementList); |
AW: Pointer of Dynamic Array
"theoretisch" sieht es so aus, als wenn es richtig wäre.
@StringList: Dort bleibt der Zeiger immer gleich und nur in dem Objekt ändert sich die Liste. Beim Array wird der Speicher immer mal wieder verschoben, weswegen sich dort der Zeiger ändert, auf den sein Pointer zeigt, aber durch den Pointer sollte man ja immer richtig direkt auf die Variable zugreifen. :gruebel: Rein logisch meinst du doch bestimmt
Delphi-Quellcode:
oder
SetLength(Elements^, Length(Elements^)+1);
Delphi-Quellcode:
aka "um 1 vergrößern" ?
SetLength(Elements^, Succ(Length(Elements^)));
|
AW: Pointer of Dynamic Array
Delphi-Quellcode:
Stimmt, so geht's einfacher.
SetLength(Elements^, Length(Elements^)+1);
Aber das Problem bleibt. Direkt nach dem Aufruf von
Delphi-Quellcode:
ist die Länge von MyElements = 0, obwohl ich sie ja definitiv erhöhe :|
ForEach
An der ForEach-Methode kann es nicht liegen, da
Delphi-Quellcode:
genau so nicht funktioniert
procedure IncDynRec(ADataPtr: Pointer);
var Elements: TElements; begin Elements:= PElements(ADataPtr)^; SetLength(Elements,Length(Elements)+1); end; |
AW: Pointer of Dynamic Array
Zunächst mal solltest du Code posten, der zumindest syntaktisch so funktionieren würde.
Zu Beginn z.B. schreibst du
Delphi-Quellcode:
, wo ein "T" nach dem "^" fehlt oder später
PElements = ^Elements
Delphi-Quellcode:
, wo das "^" im Aufruf von high(..) fehlt. Und beim letzten Post stellt sich die Frage, was "Subjects" ist? Elements wird da beispielsweise gar nicht instantiiert...
Elements^[High(Elements)].Value:= xxxx
Fehler in Code zu suchen, der vor dem Posten erst noch umgeschrieben wird, könnte vielleicht sinnlos sein, da der eigentliche Fehler durch das Umschreiben möglicherweise verschleiert wird. |
AW: Pointer of Dynamic Array
Stimmt, da sind mir wohl einige Fehler unterlaufen.
Ich versuche als meinen Code zu abstrahieren und exemplarisch anschaulich zu gestalten und ändere ihn deshalb direkt hier im Editor, deshalb fallen mir solche Fehler nicht auf. Ich werde in Zukunft darauf achten, dass ich den Code kompiliere und fehlerfrei hier poste. Vielen Dank für den Hinweis. Was die Thematik betrifft: ich habe jetzt halt eine Klasse draus gemacht und speicher alle Objekte in einer TObjectList. Somit wäre das Problem für mich nun gelöst, dennoch würde mich interessieren warum der Code nicht funktioniert. Vielleicht ergibt sich ja noch etwas. |
AW: Pointer of Dynamic Array
TObjectlist? Bist du sicher, daß du #2 verstanden hast?
|
AW: Pointer of Dynamic Array
Joar, wie man schon an der #2 sieht, kann man hier beliebig die Prozedur-Signatur (Parameter) ändern, da man nur einen untypisierten Pointer zur Callback-Prozedur rein gibt.
Delphi-Quellcode:
procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; ADataPtr: PElements; var Continue: Boolean);
begin SetLength(ADataPtr^, Length(ADataPtr^)+1); ADataPtr^[High(ADataPtr^)].Value:= xxxx; ShowMessage(IntToStr(Length(ADataPtr^))); end; procedure ExtractElements(AElementName: string; AElement: TlkJSONbase; var AData: TElements; var Continue: Boolean); begin SetLength(AData, Length(AData)+1); AData[High(AData)].Value:= xxxx; ShowMessage(IntToStr(Length(AData))); end; // Aufruf(e): var MyElements: TElements; (AJSON.Field['su'] as TlkJSONlist).ForEach(ExtractElements, @MyElements); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz