[Gelöst] Übergabe von Object an Application.QueueAsyncCall

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
soerensen3
Beiträge: 104
Registriert: Fr 22. Jun 2012, 01:51
OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
CPU-Target: 64Bit
Wohnort: Bonn

[Gelöst] Übergabe von Object an Application.QueueAsyncCall

Beitrag von soerensen3 »

Hallo erstmal..

eine Kurze Einleitung:
Im Internet habe ich folgenden Code von Mattias Gärtner gefunden, der das Programm Exiftool als Unterprozess startet um unter anderem Tags von Bildern auszulesen.
Kompletter Code:
http://free-pascal-general.1045716.n5.n ... 11423.html

Das Problem:
Der Code arbeitet mit Threads und ruft eine Callback Funktion auf um ein Ergebnis der Abfrage zu übergeben.
Das funktioniert im Grunde auch, bis auf die Tatsache, dass die Übergabe mit einer StringList erfolgt.
Erstmal der Quelltext:

Code: Alles auswählen

 
procedure TExifKeywordsParseJob.Execute;    
var
  Tags: TStringList;
  ...
begin
  ...
  Tags:= TStringList.Create;
  ...
  //Füllen von Tags mit Informationen
  ...
  Application.QueueAsyncCall(Callback, LongInt(@Tags)); // Aufrufen von CallBack und Übergabe der Tags
  //                                           @ von mir eingefügt, da es sich sonst nicht kompilieren liess
end;
 
Wenn nun die Callbackfunktion aufgerufen wird ist der Pointer auf Tags nicht mehr gültig, obwohl ich es nicht selber freigegeben habe. Anscheinend gibt der GarbageCollector von Pascal das selbständig frei.

Code: Alles auswählen

 
procedure TForm1.TagCallBack(Data: PtrInt);
var
  S: TStringList;
begin
  S:= TStringList( Data );
  Memo1.Lines.Assign( S );
  S.Free;
end; 
 
In dem Fall könnte man vielleicht einen String (der mit New und Dispose alloziiert/freigegeben wird) übergeben aber wahrscheinlich werde ich nachher in einem ähnlichen Fall Objekte übergeben müssen.

Ich hoffe ich habe mich nicht zu umständlich ausgedrückt...
Zuletzt geändert von soerensen3 am Mi 18. Jun 2014, 17:22, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10867
Registriert: Mo 11. Sep 2006, 19:01

Re: Übergabe von Object an Application.QueueAsyncCall

Beitrag von theo »

Code: Alles auswählen

procedure TForm1.TagCallBack(Data: PtrInt);
var
  S: TStringList;
begin
  S:= TStringList( Data );
  Memo1.Lines.Assign( S );
  S.Free;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Tags: TStringList;
begin
  Tags:= TStringList.Create;
  Tags.Text:='test';
  Application.QueueAsyncCall(@TagCallback, PtrInt(Tags)); 
end;    

soerensen3
Beiträge: 104
Registriert: Fr 22. Jun 2012, 01:51
OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
CPU-Target: 64Bit
Wohnort: Bonn

Re: Übergabe von Object an Application.QueueAsyncCall

Beitrag von soerensen3 »

Kleines Update:
ok nach ein paar Tests liegt es wohl doch vermutlich an der Umwandlung des Objektes in PointerInt (Der Parameter von QueueAsyncCall).
PointerInt ist vom Typ Int64.

Nur das sich jetzt erstmal keiner durch den Quelltext quälen muss..

soerensen3
Beiträge: 104
Registriert: Fr 22. Jun 2012, 01:51
OS, Lazarus, FPC: Fedora-Linux 23 (Korora) Lazarus 1.6 FPC 3.0
CPU-Target: 64Bit
Wohnort: Bonn

Re: Übergabe von Object an Application.QueueAsyncCall

Beitrag von soerensen3 »

Oh habe deine Antwort übersehen, da du kurz vor mir geschrieben hast.
Vielen dank! Das war die Lösung!

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: [Gelöst] Übergabe von Object an Application.QueueAsyncCa

Beitrag von Christian »

Es gibt beim fpc keinen Garbage Collector
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Antworten