Recent

Author Topic: [soled] StringList.CustomSort - how to migrate from Delphi?  (Read 1581 times)

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #15 on: September 10, 2022, 05:08:36 pm »
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H-}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.  
  19.   public
  20.   end;
  21.  
  22. var
  23.   Form1: TForm1;
  24.  
  25. implementation
  26.  
  27. {$R *.lfm}
  28.  
  29. { TForm1 }
  30. Function MySort(List:TstringList;Index1,Index2:Integer):Integer;
  31. Begin
  32.   Result := ShortInt(List[Index1][1])-ShortInt(List[Index2][1]);
  33. end;
  34.  
  35. procedure TForm1.Button1Click(Sender: TObject);
  36. var S:TstringList;
  37. begin
  38.   S := TStringList.Create;
  39.   S.CommaText := '9,2,1,5,0,7,3,4,8,6';
  40.   S.CustomSort(@MySort);
  41.   Caption := S.CommaText;
  42.   S.Free;
  43. end;
  44.  
  45. end.
  46.  

His my stab at it!.. :o
The only true wisdom is knowing you know nothing

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: StringList.CustomSort - how to migrate from Delphi?
« Reply #16 on: September 10, 2022, 05:47:18 pm »
    • the call to TStringList.CustomSort has only one single parameter - the functon to be called by StringList. A pointer to a function with specific signaure. Read any Pascal tutorial about procedure types.
    • your function TFrame_Korrelationen.StringListSortComparefn2(List: TStringList; Index1, Index2: Integer): Integer; does not have three paramaeters, it had FOUR parameters. You forgot about Self, which is a parameter too, albeit "hidden" or "invisible" one. This 4th paramneter is exactly why TStringList can not call this your function.
    No, that function doesn't have a "hidden" parameter.
    The reason for the initial error message is much simpler.

    Calling SL_SUB.CustomSort(StringListSortComparefn2) (without the @) in OBJFPC mode, will try to EXECUTE the StringListSortComparefn2 function without any parameters.

    Always remember...
    With OBJFPC mode you need @ So SL_SUB.CustomSort(@StringListSortComparefn2)
    With DELPHI mode you don't need @  So SL_SUB.CustomSort(StringListSortComparefn2)

    Second problem, if you use the correct call, is that the sort method can't be part of the class.
    The error is then
    Quote
    Incompatible type for arg no. 1: Got "<procedure variable type of function(TStringList;LongInt;LongInt):LongInt of object;Register>", expected "<procedure variable type of function(TStringList;LongInt;LongInt):LongInt;Register>
    Just move the StringListSortComparefn2 to outside the class and it will work correctly.

    BTW The same goes for Delphi (I just checked). You can't use a class function for the CustomSort call.
    You'll get a error "[dcc32 Error] E2009 Incompatible types: 'regular procedure and method pointer'"

    So as one of the first post stated.
    All you need to do is
    1) Use {$MODE DELPHI}{$H+} and move the sort function outside the class.
    or
    2) use {$MODE OBJFPC}{$H+}, Add the @ in front as required, and move the sort function outside the class.


    Arioch

    • Sr. Member
    • ****
    • Posts: 421
    Re: StringList.CustomSort - how to migrate from Delphi?
    « Reply #17 on: September 10, 2022, 06:38:31 pm »
    No, that function doesn't have a "hidden" parameter.

    BTW The same goes for Delphi (I just checked). You can't use a class function for the CustomSort call.

    Yes, it does. "Self" is funciton parameter, passed as all other regular parameters in registers or in stack, see calling conventions.

    Yet, is obviously won't, because the StringList has not value for the th parameter - Self. The screenshot of both Delphi error and code was in the post you replied to.

    Arioch

    • Sr. Member
    • ****
    • Posts: 421
    Re: StringList.CustomSort - how to migrate from Delphi?
    « Reply #18 on: September 10, 2022, 06:41:41 pm »
    Code: Pascal  [Select][+][-]
    1. {$H-}
    2.  

    And that is your problem.  The TStringList's "string" and your function's "string" are different types.

    Remember, string is not the real, comprehensively defined type, it is a switchable alias. And you switched that alias to different type than the type used by TStringList.

    I do not know why you insist on {$H-} but if you do - use UnicodeString in your comparator function. Or switch back to {$H+} before the comparator function, if this switch can be changed in the middle of the sources.

    related: https://forum.lazarus.freepascal.org/index.php/topic,60528.0.html

    ----

    and don't tell me your Delphi project is compiled with long strings turned off, with $H- or equal etting in Project Options :-)
    « Last Edit: September 10, 2022, 06:46:25 pm by Arioch »

    Nicole

    • Hero Member
    • *****
    • Posts: 970
    [solved] StringList.CustomSort - how to migrate from Delphi?
    « Reply #19 on: September 15, 2022, 12:20:30 pm »
    Thank you all for those interesting postings!

    The solution for Lazarus reads:
    SL_SUB.CustomSort(@StringListSortComparefn2);

    This worked in Delphi:
    SL_SUB.CustomSort(StringListSortComparefn2);

    ►►► @
    makes the difference

    wp

    • Hero Member
    • *****
    • Posts: 11916
    Re: [solved] StringList.CustomSort - how to migrate from Delphi?
    « Reply #20 on: September 15, 2022, 12:53:27 pm »
    The solution for Lazarus reads:
    SL_SUB.CustomSort(@StringListSortComparefn2);

    This worked in Delphi:
    SL_SUB.CustomSort(StringListSortComparefn2);

    ►►► @
    makes the difference
    When you write {$MODE Delphi} at the top of your unit the Delphi syntax (without @) will work, too.

    Nicole

    • Hero Member
    • *****
    • Posts: 970
    Re: StringList.CustomSort - how to migrate from Delphi?
    « Reply #21 on: September 15, 2022, 01:41:30 pm »
    Indeed!
    Thank you for this hint.
    I was told so before, it was one of the very first replies as far as I remember. It did not work for me. Perhaps I had tried too much in the meanwhile and added an error.

    I confirm: mode delphi works as well.

     

    TinyPortal © 2005-2018