Einzelnen Beitrag anzeigen

BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#1

array of const für spätere Verwendung speichern

  Alt 31. Jan 2016, 17:31
Hallo zusammen,

ich kämpfe hier gerade mit einem Problem. Ich habe eine Methode geschrieben, welche als Parameter "array of const" beinhaltet. Dieses "array of const" soll zu einem späteren Zeitpunkt an die "Format"-Funkion übergeben werden. "array of const" ist ja bekanntermaßen ein "array of TVarRec". Also habe ich das auch so deklariert (Strukturen und Code für bessere Übersichtlichkeit gekürzt):

Delphi-Quellcode:
  PRec = ^TRec;
  TRec = record
    Params: array of TVarRec;
  end;
In meiner Methode werden die Werte dann mit folgendem Code zwischengespeichert:

Delphi-Quellcode:
procedure Something(const Args: array of const);
var
  RecPtr: PRec;
begin
  New(RecPtr);
  SetLength(RecPtr^.Params, Length(Args));
  for I := Low(Args) to High(Args) do
    RecPtr^.Params[I] := Args[I];
end;
Soweit so gut. Der generierte Record wird einer Thread-Liste abgelegt und dann von einer anderen Thread verarbeitet. Das funktioniert auch alles bestens, solange ich Strings oder Konstante Werte in "Args" übergebe. Übergebe ich aber z.B. eine numerische Variable, so ist diese nur verfügbar, solange ich in der Methode "Something" bin. Beim Verlassen der Methode wird diese finalisiert und löst dann natürlich eine Exception aus, sobald auf diese zugegriffen wird. Ich habe das getestet indem ich in der Methode geblieben bin, bis die Thread die Parameter verarbeitet hatte...

Zum weiteren Verständnis: Die Thread holt die Records nacheinander vom Puffer (TThreadList) und verarbeitet diese asynchron zum aufrufenden Programm. Leider können die Args erst dort verarbeitet werden, da die endgültigen Formatstrings erst in der Thread verfügbar sind...

Mir fällt leider im Moment keine elegante Lösung ein. Irgendwie müsste ich mich da manuell um "Initialize" und "Finalize" kümmern. Hat jemand von euch eine Idee? Ich hoffe das Problem ist einigermaßen verständlich geschildert und ich habe mich beim "Pseudo"-Code nicht zu sehr vertippt .

PS: Eine Lösung wäre bei bestimmten Typen (z.B. VExtended) die als Pointer gespeichert werden diese mit New(RecPtr^.Params[I].VExtended) dynamisch zu allokieren und den Wert mit RecPtr^.Params[I].VExtended^ := Args[I].VExtended^ zu übernehmen. Später müsste dann dieser mit Dispose(RecPtr^.Params[I].VExtended) dann wieder freiegeben werden. Ist aber sehr umständlich und man müsste die richtigen Typen ermitteln und das bei allen (auch zukünftigen) Typen korrekt durchführen. Ist nicht sehr elegant.

Freue mich über alle Antworten!

Alex
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)

Geändert von BigAl (31. Jan 2016 um 18:34 Uhr)
  Mit Zitat antworten Zitat