Kontext von Callback-Funktionen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Kontext von Callback-Funktionen

Beitrag von RSE »

Hallo!

In welchem Kontext laufen eigentlich Callback-Funktionen? Was kann ich verwenden, was nicht? Ich hab gar nicht dran gedacht und drauf los programmiert. Als ich fertig war, flogen mir die Fehler um die Ohren. :oops:

Ich habe eine von TList abgeleitete Klasse, in der ich die Funktion TList.Sort aufrufe. Diese verlangt eine Callback zum Vergleich der Elemente. Der Klassenbezeichner meiner Klasse zum Typecast ist z.B. bekannt, die Parametervariable der Funktion, in der ich TList.Sort aufrufe widerum nicht.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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: Kontext von Callback-Funktionen

Beitrag von Christian »

Was meinst du mit kontext ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Kontext von Callback-Funktionen

Beitrag von mschnell »

Was meinst Du mit Kontext ?

z.B.:

Objekt-Kontext:

So etwas (also einen self-Pointer) haben nur Funktionen / Prozeduren, deren Typ mit "of Object" definiert ist. Der Kontext (Self-Pointer) unter dem der Code, der das ":=" ausführt, wird bei der Zuordnung in der Prozeduralen Variable gespeichert. Also: Kontext des Variablen-Wert-Setzers.


Thread-Kontext:

Der Thread-Kontext wird beim Aufruf einer in einer prozeduralen Variablen nicht verändert. Also: Kontext des Variablen-Wert-Benutzers.

-Michael
Zuletzt geändert von mschnell am So 7. Sep 2008, 22:36, insgesamt 1-mal geändert.

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: Kontext von Callback-Funktionen

Beitrag von Christian »

Im Kontext des Objektes zu der die Callback gehört und im Main Thread.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Kontext von Callback-Funktionen

Beitrag von RSE »

Das ist besagte Funktion:

Code: Alles auswählen

procedure TAktionen.SortBy(const SortStr: String);
// TAktionen ist mein Nachkomme von TList
  function Compare(Item1,Item2: Pointer): Integer;
  var
    i: integer;
  begin
    if SortStr = 'Start' then begin // SortStr kennt er nicht zur Laufzeit
      if trunc(TAktion(Item1).Start) = trunc(TAktion(Item2).Start) then
// eine Startzeit (TDateTime)
        result := 0
      else if trunc(TAktion(Item1).Start) < trunc(TAktion(Item2).Start) then
// ist das trunc hier noch sinnvoll (damit ist es eine Integeroperation)?
        result := -1
      else
        result := 1;
    end else if SortStr = 'Ende' then begin
      ...
    end;
    if (not FMain.Aktionen.SortedRev) and (result <> 0) and
       (FMain.Aktionen.SortedBy = SortStr) then
// Referenz auf Mainform FMain, unqualifizierter Zugriff
// auf SortedRev ergibt ein SIGSEGV-Fehler
      result := -result;
  end;
begin
  Sort(TListSortCompare(@Compare));
  if SortedBy = SortStr then
    SortedRev := not SortedRev
  else begin
    SortedBy := SortStr;
    SortedRev := false;
  end;
end;
Mir gefällt dabei nicht die Referenzierung von FMain, da die Funktion ja innerhalb TAktionen definiert ist. Wie ich an SortStr herankomme, weiß ich noch gar nicht.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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

Re: Kontext von Callback-Funktionen

Beitrag von theo »

Ich weiss ja nicht genau was das werden soll, aber mach doch bei "Compare" einfach nur das was der Name aussagt: Den Vergleich!
Das ganze "if SortStr = 'Start' ..." gehört doch nicht in diese Funktion sondern nach SortBy.
Wenn du für "Ende" was anderes machen muss, mach eine zweite "Compare" Funktion. (Compare2)

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Kontext von Callback-Funktionen

Beitrag von RSE »

Wenn ich das alles auslagern würde, bräucht ich 10 verschiedene Compare-Funktionen... mit SortStr überprüfe ich, um welche Spalte eines Grids es sich handelt. Das jetzt alles zu erläutern geht hier zu weit. Ich brauche diesen Vergleich an dieser Stelle.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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

Re: Kontext von Callback-Funktionen

Beitrag von theo »

RSE hat geschrieben: Das jetzt alles zu erläutern geht hier zu weit. Ich brauche diesen Vergleich an dieser Stelle.
Na gut, dann kann man dir aber auch nicht richtig helfen. Riecht einfach ein bisschen nach Holzweg das Ganze.
Wenn es aber wirklich so sein soll, dann implementiere den Quicksort selbst und verzichte auf TList.Sort mit dem Callback.

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Kontext von Callback-Funktionen

Beitrag von RSE »

Wenn du unbedingt darauf bestehst hier die Geschichte: Ich stelle Daten tabellarisch dar. Jede Zeile bildet eine Einheit, es gibt 5 Spalten. Da ich manche Zeilen hervorheben will, muss ich TDrawGrid statt TStringGrid verwenden (http://www.lazarusforum.de/viewtopic.php?f=18&t=1955" onclick="window.open(this.href);return false;). Für die Daten habe ich also eine Klasse erstellt: TAktion. Dann habe ich TAktionen von TList abgeleitet, um die TAktion-Objekte in einer Liste zu speichern. In DrawGrid.DrawCell stelle ich die Daten entsprechend dar. Mein DrawGrid hat die Einstellung TitleStyle = tsNative. Über Columns.Title.Caption habe ich die Beschriftung der FixedRow angegeben (u.a. "Start" und "Ende"). Da ich eingestellt habe, dass der User die Spalten verschieben kann, kann ich deren Anordnung nur noch über den Test auf Title.Caption ermitteln. Bei Klick auf die FixedRow wird OnHeaderClick ausgelöst. Dort ermittle ich, auf welche Spalte geklickt wurde, und rufe z.B. SortBy('Start'); auf. In SortedBy wird der String gespeichert, nach dessen Spalte sortiert worden ist (wird gelöscht in Add und bei Änderungen). Bei erneutem Klick auf die selbe Spalte (SortedBy = Title.Caption), soll rückwärts sortiert werden. Dazu brauche ich SortedRev. Dort wird gespeichert, ob bereits rückwärts sortiert ist.

So, jetzt weißt du Bescheid :wink:
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Kontext von Callback-Funktionen

Beitrag von RSE »

Gibt´s da keine elegantere Möglichkeit, als eine eigene Sortierroutine zu schreiben? Ich werd mal einen Feature-Request machen, dass man an Sort einen Zeiger auf eigene Daten mit übergeben kann, den man dann in der Callback übergeben bekommt.
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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: Kontext von Callback-Funktionen

Beitrag von Christian »

Nur mal als anmerkung TAction gibts als Klasse schon könte zu Problemen führen wenn du Actions verwenden willst.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

RSE
Beiträge: 462
Registriert: Mi 30. Jul 2008, 13:11
OS, Lazarus, FPC: WinXP SP3 (L 0.9.28.2 FPC 2.2.4)
CPU-Target: 32Bit
Kontaktdaten:

Re: Kontext von Callback-Funktionen

Beitrag von RSE »

Ich benutze Actions, aber das schreibt man anders als meine Aktionen ;-)
Seit er seinen neuen Computer hat, löst er alle Probleme, die er vorher nicht hatte!

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

Re: Kontext von Callback-Funktionen

Beitrag von theo »

RSE hat geschrieben:Gibt´s da keine elegantere Möglichkeit, als eine eigene Sortierroutine zu schreiben? Ich werd mal einen Feature-Request machen, dass man an Sort einen Zeiger auf eigene Daten mit übergeben kann, den man dann in der Callback übergeben bekommt.
Kannst ja deine TAktion Klasse um irgendwelche Properties erweitern, dann wird da übergeben soviel du willst.
Oder globale Variablen. Gibt höchstens bei Multi-Threading Probleme (s.a. Threadvar).

Antworten