TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp [GELÖST]

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp [GELÖST]

Beitrag von multiplatform-coder »

Ich habe mich darauf verlassen dass ja in der Unit fgl ger Funktiostyp schon vorgegeben ist und dann einfach meine Funktionen passen definiert.


Ich bekomme aber folgenden Compilerfehler:

myfile.inc(378,43) Error: Incompatible type for arg no. 1: Got "<address of function(Pointer;Pointer):LongInt;Register>", expected "TFPGObjectList$1$crc302B5C15.<procedure variable type of function(const TmyType;const TmyType):LongInt;Register>"


Daten von Typ TmyType sollen in der Liste gespeichert und dann sortiert werden.

Code: Alles auswählen

if Ascending then Sort(@CompareAscending) else Sort(@CompareDescanding);  

Code: Alles auswählen

function CompareDescending(const Item1,tem2: TmyType): LongInt; Register;  //absteigend
begin
  if TmyType(Item1).comparefield < TmyType(tem2).comparefield then Result := -1 else
  if TmyType(Item1).comparefield > myType(tem2).comparefield then Result := 1 else Result := 0;
end;

//für CompareAscending -> Result entgegengesetztes Vorzeichen.

Warum meldet mein Compler fps 3.2.2 hier den obigen Fehler. Wie muss ich meine Funktion hier definieren? Oder was muss ich hier anders schreiben und wie?
Zuletzt geändert von multiplatform-coder am Sa 26. Apr 2025, 09:23, insgesamt 2-mal geändert.

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

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von theo »

Was ist "TtuiBox" und warum, wenn du nachher auf "TmyType" castest?
Tippfehler:
if Ascending then Sort(@CompareAscending) else Sort(@CompareDescanding);

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Die TuiBox ist für ein konkretes Projekt, ich will aber eine Lösung die für jeden beliebigen Datentyp passt. Also auch ohne TuiBox. Will nicht bei jedem Datentyp wieder neu rumbastenln. Deshalb die Generics und deshalb TFPGObjectlist. Ich will den Compilerfehler eliminieren und TuiBox ist es halt in meinem konkreten Quellcode, soll aber auch allgemein funktionieren.


Ich habe deshalb auf TmyType umgeschrieben um, niemanden hier zu verwirren, habe aber vergessen das auch in meiner Sort Funktion im Headr zu tun. Ich suche eine Lösung die für alle Datentypen passt. Also bitte nicht am TuiBox Typ aufhängen.

ist das "@" Zeichen dort in der Sort Funktion falsch? Wenn ich das aber weg lasse kommt Compilerfehler Funtionsaufruf mit falscher Parameterzahl! Ich will doch nur den Funktionszeiger an die Sort Funktion übergegeen oder muss ich bei dieser konkreten Sort Funktion einen anderen Weg gehen. Aber bitte wechen !!!!! ??? Ich stehe auf den Schlauch. Warum ist das so kompliziert und WO gibt es die passenmde Doku dazu wo das verständlich erklärt ist??? Wo also kann ich da nachlesen???? Mit Programmbeispiel bitte ? Oder in welchem Lazarus Ornner finde ich dazu passenden Quellcode der mir den richtigen Weg zeigt? Ich habe das jetzt auf TmyType geändert. War im Quellcode halt TtuiBox.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2805
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von m.fuchs »

multiplatform-coder hat geschrieben: Di 15. Apr 2025, 16:53 Ich habe deshalb auf TmyType umgeschrieben um, Ich suche eine Lösung die für alle Datentypen passt.
Das geht aber nicht.

Die generischen Liste funktioniert gut für alle Datentypen - weil die Verwaltung eine Liste im Speicher für jeden Typen praktisch gleich abläuft.

Aber Sortierungen sind natürlich nicht gleich, denn es gibt keine allgemeingültige Lösung um zwei Variablen miteinander zu vergleichen.
Wäre dies möglich, würde es dies auch bereits in den generischen Listen implementiert sein.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Nun gut, aber so eine Comparefunc gibt es doch laut Wiki und der Beschreibung für TFPGObjectlist. Fort sind die einzelnen Methoden anklickbar. Und für die Sort Methoder der TFPGObjectlist erhalte ich das hier:

Code: Alles auswählen

 public procedure TFPGObjectList.Sort(

  Compare: TCompareFunc

);
Und mein Compiler hat bei seiner Fehlermeldung das angezeigt was im Eingangspost schon angegeben ist, also schaut meine Funktion so aus:

Code: Alles auswählen

function Compare(const item1: TmyType; Const Item2: TmyType): Longint; wie mir die Compilermeldung unter "expected" anzeigt.
Warum akzeptiert der Compiler in der Sort Funktion nun mein "@" Zeichen nicht und zeigt aber bei fehlendem "@" Zeichen "falsche Parameter Anzahl an wo ich doch nur die Adresse meiner Compare Funktion übergeben will. Ich habe mal irgendwo gelesen dass bei Funktionszeigern die Parameter nicht mit übergeben werden dürfen.

Ich kompiliere mit: {$MODE OBJFPC}{$H+}

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

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von theo »

Man sieht ja nicht was du machst. Was soll man dazu sagen?
Hier ist ein Beispiel:
https://github.com/silvercoder70/code-e ... ample6.lpr
Zusammen mit uperson.pas sollte das funktionieren.

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Danke, das Beispiel hilft schon mal! :)

Aber wie sieht denn die TComparefunc aus? Muss die in einer abgeleiteten Klasse als Methode definiert werden oder muss die außerhalb der Klasse definiert werden? Wie muss die Parameterliste aussehen? Es gibt da verschiedene Parameterlisten. In Deinem Beispiel ist die Funktion nicht mit aufgeführt. Mir genügt hier die allereinfachste Variante. Ich will zuerst mal lernen wie man so eine Comparefunc überhaupt definiert, vom Urschleim an, wie ein Anfänger, danach erst kann ich den nächsten Schritt gehen. Und wegen meines Usernamen, zuerst für Windows, später auch für Linux. Scheint ja recht systemabhängig zu sein das alles. Will zuerst also die einfachste funktionierende Variante für Windows in einer TFPGObjectList<TIrgendein_Typ>; Dein Beispiel ist für eine TFPGList. Ist da ein Unterschied in der Funktionskopf Definition der Comparefunc?

Ist dieser Funktionskopf für die TFPGList korrekt: function Comparefunc(Item1,Item2: Pointer): Integer; ? Oder muss der Funktionskopf für die Comparefunc anders definiert werden?

Dieser Typ TIrgendein_Typ soll ein Klassentyp sein, dessen Vergleichsfeld ich mit TIrgendein_Typ(Item).Vergleichsfeld ansprechen will, so das auch geht. Wie muss die zugehörige Comparefunc da aussehen, das Beispiel zeigt ja schon mal die Übergabe an die Sort Methode, MIT dem @ Zeichen am Anfang der Funktion???

Was ich erreichen will ist zuerst mal die korrekte Syntax zu verstehen und zu schreiben. Was sollte ich damit machen können, wenn ich da schon Probleme habe.

Die Übergabe der Comparefunc an die Sort Methode ist schon mal gezeigt. Mir fehlt aber nun noch der Funktionskopf für die Compare Funktion. Laut Lazarus Doku gibt es da mehrere Versionen je nach Listenobjekttyp. Welche davon brauche ich für die TFPGList und welche für die TFPGObjectList?
Zuletzt geändert von multiplatform-coder am Di 15. Apr 2025, 20:37, insgesamt 1-mal geändert.

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

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von theo »

Ich habe oben geschrieben:
theo hat geschrieben: Di 15. Apr 2025, 18:38 Zusammen mit uperson.pas sollte das funktionieren.
Diese Unit ist im gleichen Verzeichnis.

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Ok, danke soweit, ich guck mir das jetzt sukzessive an. Habe die anderen Files jetzt erst gesehen, vorhin kam ich sofort auf das example 6 und habe nicht auf die linke Seite geguckt wo die anderen Dateien zu finden sind. Sorry, ich glaub ich hör für heute auf, morgen bin ich konzentrierter dafür. uPerson mit der so dringend gesuchten Vergleichsfunktion ist auch dabei, aber morgen ist auch noch ein Tag. :wink:

PascalDragon
Beiträge: 945
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von PascalDragon »

multiplatform-coder hat geschrieben: Di 15. Apr 2025, 14:53 Warum meldet mein Compler fps 3.2.2 hier den obigen Fehler. Wie muss ich meine Funktion hier definieren? Oder was muss ich hier anders schreiben und wie?
Weiß nicht, was ich dir sagen soll, aber hier funktioniert ein entsprechendes Beispiel:

Code: Alles auswählen

program tgensort;

{$mode objfpc}

uses
  fgl;

type
  TTest = class

  end;

  TTestList = specialize TFPGObjectList<TTest>;

function CompareTest(const aLeft, aRight: TTest): Integer;
begin
  if PtrUInt(aLeft) > PtrUInt(aRight) then
    Result := 1
  else if PtrUInt(aLeft) < PtrUInt(aRight) then
    Result := -1
  else
    Result := 0;
end;

var
  t: TTestList;
begin
  t := TTestList.Create;
  try
    t.Sort(@CompareTest);
  finally
    t.Free;
  end;
end.
Wenn dir das nicht hilft, dann zeig bitte ein vollständiges Beispiel, das dein Problem zeigt.
FPC Compiler Entwickler

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

PascalDragon hat geschrieben: Di 15. Apr 2025, 22:59
multiplatform-coder hat geschrieben: Di 15. Apr 2025, 14:53 Warum meldet mein Compler fps 3.2.2 hier den obigen Fehler. Wie muss ich meine Funktion hier definieren? Oder was muss ich hier anders schreiben und wie?
Weiß nicht, was ich dir sagen soll, aber hier funktioniert ein entsprechendes Beispiel:

Code: Alles auswählen

program tgensort;

{$mode objfpc}

uses
  fgl;

type
  TTest = class

  end;

  TTestList = specialize TFPGObjectList<TTest>;

function CompareTest(const aLeft, aRight: TTest): Integer;
begin
  if PtrUInt(aLeft) > PtrUInt(aRight) then
    Result := 1
  else if PtrUInt(aLeft) < PtrUInt(aRight) then
    Result := -1
  else
    Result := 0;
end;

var
  t: TTestList;
begin
  t := TTestList.Create;
  try
    t.Sort(@CompareTest);
  finally
    t.Free;
  end;
end.
Wenn dir das nicht hilft, dann zeig bitte ein vollständiges Beispiel, das dein Problem zeigt.

Im Grunde nichts Besonderes, nur das hier:

Code: Alles auswählen

unit usort;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils, tui.core, fgl;


function CompareAscending(const Item1,Item2: Pointer): Integer;   //aufsteigend

function CompareDescending(const Item1,Item2: Pointer): Integer;   //absteigend

type
  TData = TFPObjectList;
  TSortedItems = class (TData)
  private
     FAscending: Boolean;
  public
     procedure SetAscanding(AValue: Boolean);
     procedure GetFrom(AComponent: TComponent);
     procedure GiveSorted(var asorted: TComponent);

     property Ascending: Boolean read FAscending write FAscending;
  end;


implementation
function CompareAscending(Item1,Item2: Pointer): Integer;   //aufsteigend
begin
  if TData(Item1).FieldToCompare < TData(Item2).FieldToCompare
     then Result := 1 else
  if TData(Item1).FieldToCompare > TData(Item2).FieldToCompare
     then Result := -1 else Result := 0;
end;

function CompareDescending(Item1,Item2: Pointer): Integer;   //absteigend
begin
  if TData(Item1).FieldToCompare < TData(Item2).FieldToCompare
     then Result := -1 else
  if TData(Item1).FieldToCompare > TData(Item2).FieldToCompare
     then Result := 1 else Result := 0;
end;

procedure TSortedItems.SetAscanding(AValue: Boolean);
begin
  if FAscending <> AValue then
  begin
    FAscending := AValue;
  end;
end;

procedure TSortedItems.GetFrom(AComponent: TComponent);
var ix: Integer;
begin
  ix := 0;
  if Assigned(AComponent) then
  while ix < AComponent.ComponentCount do
  begin
    Add(TData(AComponent.Components[ix]));
    //die Inhalte der Vergleichsfelder sind in von TComponent
    //abgeleiteten Klassen enthalten
    inc(ix);
  end;
  if Ascending then Sort(@CompareAscending) else Sort(@CompareDescending);
  //An dieser Stelle meckert der Compiler  <fpc 3.2.2>
end;

procedure TSortedItems.GiveSorted(var asorted: TComponent);
var ix: Integer;
begin
  ix := 0;
  while ix < asorted.Count do
  begin
     asorted.RemoveComponent(TData(asorted.Components[ix]));
     inc(ix);
  end;
  ix := 0;
  while ix < count do
  begin
    asorted.InsertComponent(TData(Items[ix]));
    inc(ix);
  end;
end;


end.
Ein Beispiel könnten so aussehen:

Code: Alles auswählen


type 
TData = class(TComponent)
   Name: string;
   Telefonnummer: String;
   Kundennummer: Integer;
   constructor create(AOwner: TComponent);
   procedure DoSomethingWith;
   Destructor Destroy; override;
end;

   constructor TData.create(AOwner: TComponent);
   begin
       inherited  
   end;
   procedure TData.DoSomethingWith;
   begin
   end;
   Destructor TData.Destroy; override;
   begin
      inherited
   end;
  
Der Compiler meckert beim @ Zeichen.

Ich baue inzwischen meinen Quellcode um und stodiere das Github Beispiel. Bevor ich mehr Infos geben kann, muss ich zuerst meinen Quellcode umbauen. Wenn bei Euch der Prozedurzeiger funktioniert, muss ich eh den kritischen Teil aus meinem Code sinnvoll auslagern um das Problem einzugrenzen, das aber will ich alleine schaffen, da ich keinen logischen Fehler bekomme sondern der Compiler blockt bereits ab

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

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von theo »

Schick doch mal einen zusammenhängenden Code.
Deine Schnippsel versteht man nicht.

Code: Alles auswählen

type
  TData = TFPObjectList;
  TSortedItems = class (TData)

Code: Alles auswählen

type 
TData = class(TComponent)
Ist TData jetzt ein Alias für TFPObjectList oder eine Ableitung von TComponent?
Lies das Ganze nochmal in Ruhe durch.

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Ich bin gerade dabei die Beispiele im Github Link durch zu arbeiten. Und NEIN, TDate ist mein Alias für die Nutzdaten die ich sortieren will.

TData = class(TComponent) //muss von TComponent abgeletet sein, weil es um Datenfelder innerhalb von Komponenten geht, nach denen ich sortieren will.
Tag: Integer; //könnte so ein Feld sein
end;

Meine TFPGList wäre dann: eine specialize TFPGList<TData>. wie im Github Beispiel mit TPerson.

Aber gut, da baue ich mal ein allgemeines Beispiel zusammen. Muss doch zu knacken sein warum der Prozedurzeiger in der Sort Methode nicht anerkannt wird. Das Beispiel folgt in den nächsten Tagen, weil ich dazu doch mehr erklären muss. Will das deshalb bissl schön didaktisch aufbereiten. Aber ich fürchtre dass in meinem Code moch was ganz Anderes faul ist.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2805
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von m.fuchs »

1.) Wie theo auch schon festgestellt hat: das ist alles ein bisschen wirr. Poste den kompletten Code deine Datenklasse, deiner Liste (also die Spezialisierung) und deiner Sortiermethoden.

2.) Du fummelst da mit mit Pointern herum in deinen Sortiermethoden. Das ist mit Sicherheit falsch, den das müssen ja Funktionen sein, die zwei Objekte deiner Datenklasse übergeben bekommen.
multiplatform-coder hat geschrieben: Mi 16. Apr 2025, 12:23 Muss doch zu knacken sein warum der Prozedurzeiger in der Sort Methode nicht anerkannt wird.
3.) Na weil er nicht der erwarteten Form entspricht Warum nicht? -> Siehe 2.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

multiplatform-coder
Beiträge: 59
Registriert: Do 20. Apr 2023, 18:25

Re: TFPGObjectList -> Sort() Funktion, Typdefinition Funktionstyp

Beitrag von multiplatform-coder »

Ok, da bringe ich den Code mal hierher. Mach ich morgen. Ich blick selber nicht mehr durch bei dem Code. Irgendwas habe ich da durcheinander gebracht. Muss aber den Code selber erst mal ordnen, der ist über zwei Units verteilt. Da muss ich den raus kopieren und in eine Unit bzw in den Thread kopieren.

Antworten