Generics Delphi <-> Lazarus/FPC Umwandlung

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

Ich habe Probleme beim verstehen der Unterschiede bei den Generics zwischen Delphi und FPC/Lazarus.

Ich habe in Delphi eine TList<>, was ist die Entsprechung im FPC ? TFPGList dürfte es nicht sein.

Code: Alles auswählen

 
{$mode delphi}
..........
uses
     {$IFDEF FPC}
     SysUtils,
     fgl;
     {$ELSE}
     system.SysUtils,
     Generics.Collections;
     {$ENDIF}
...........
type
  TByteSegments = class(.....)
  private
{$IFDEF FPC}
    FList: TFPGList<TArray<Byte>>;
{$ELSE}
    FList: TList<TArray<Byte>>;
{$ENDIF}
    .......
     constructor Create;
    .......
  end;
 
constructor TByteSegments.Create;
begin
  {$IFDEF FPC}
  FList := TFPGList<TArray<Byte>>.Create; // <-- Das geht nicht
  {$ELSE}
  FList := TList<TArray<Byte>>.Create;
  {$ENDIF}
   inherited Create;
end;
 
 


Wie komme ich da weiter ?

In http://www.freepascal.org/docs-html/ref/refsu45.html steht folgendes, jetzt verstehe ich nicht, warum das obige nicht funktioniert. TArray<Byte> ist ja auch nur ein Typ, wie LongInt. Irgendwo habe ich da einen Denkfehler.

Code: Alles auswählen

8.5.5 Scope considerations
 
Delphi mode allows use a generic specialized type without explicitly declaring it. That means the following is possible:
 
var 
  t: TTest<LongInt>; 
begin 
  t := TTest<LongInt>.Create
end;
In objfpc mode, the type must be declared specifically.


Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von marcov »

0. delphi mode nutzen
1. in Delphi namespace Präfixen einstellen (auch für XE2- Kompatibilität) so das man einfach "sysutils" nutzen kann, und alle System.* und winapi.* Unsinn rausholen.
2. Die relevante units (generics.*) aus Trunk (rtl-generics), und einfach Herkompilieren

-> fertig

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

marcov hat geschrieben:0. delphi mode nutzen
1. in Delphi namespace Präfixen einstellen (auch für XE2- Kompatibilität) so das man einfach "sysutils" nutzen kann, und alle System.* und winapi.* Unsinn rausholen.
2. Die relevante units (generics.*) aus Trunk (rtl-generics), und einfach Herkompilieren

-> fertig

Das ist eine fertige Bibliothek (ZXing.Pascal) für die Erkennung von Barcodes.
Zitat:

Code: Alles auswählen

ZXing ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages.


Lazarus 1.7 r54119M FPC 3.1.1 i386-win32-win32/win64
0. -> done (Ist schon bei obigen drinnen gewesen
1. -> mit bedingter Kompilierung gemacht
2. -> gemacht, aber der Fehler bleibt gleich. wieder TList<TArray<Byte>> verwendet. Mit den Generics.* wird das erkannt, aber das .Create nicht.

Code: Alles auswählen

Projekt kompilieren, Ziel: vclTestApp.exe: Exit code 1, Fehler: 2, Warnungen: 1
ZXIng.ByteSegments.pas(53,6) Warning: Constructor should be public
ZXIng.ByteSegments.pas(87,31) Error: Illegal expression
ZXIng.ByteSegments.pas(87,32) Fatal: Syntax error, ";" expected but "identifier CREATE" found
Codetools, Fehler: 1
ZXIng.ByteSegments.pas(47,24) Error: > erwartet aber < gefunden
 
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von marcov »

Etwas rummgesucht und es ist ein bekanntes Problem. Einfach herum arbeiten durch

Code: Alles auswählen

 
 
Type
   tbytearray = tarray<byte>;
 
flist:=tlist<tbytearray>.create;
 

moeglich geht da was schief mit der >> Operator und zwei schließende generics Deklarationteilen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

marcov hat geschrieben:Etwas rummgesucht und es ist ein bekanntes Problem. Einfach herum arbeiten durch


Danke für die Info :D . Wie immer habe ich eine Menge über Generics gefunden, auch das die mittlerweile in den fpc gewandert sind, nur in Mantis bin ich nicht darüber gefallen :oops: .

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

Beim herumarbeiten bin ich auf folgendes Konstukt gestossen:

Code: Alles auswählen

 
var
  CODE_PATTERNS: TArray<TArray<Integer>>;
........
  CODE_PATTERNS :=  [[2, 1, 2, 2, 2, 2], // 0
  [2, 2, 2, 1, 2, 2], [2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 2, 3],
    [1, 2, 1, 3, 2, 2], [1, 3, 1, 2, 2, 2], // 5
  [1, 2, 2, 2, 1, 3], [1, 2, 2, 3, 1, 2], [1, 3, 2, 2, 1, 2],
    [2, 2, 1, 2, 1, 3], [2, 2, 1, 3, 1, 2], // 10
  [2, 3, 1, 2, 1, 2], [1, 1, 2, 2, 3, 2], [1, 2, 2, 1, 3, 2],
    [1, 2, 2, 2, 3, 1], [1, 1, 3, 2, 2, 2], // 15
  [1, 2, 3, 1, 2, 2], [1, 2, 3, 2, 2, 1], [2, 2, 3, 2, 1, 1],
    [2, 2, 1, 1, 3, 2], [2, 2, 1, 2, 3, 1], // 20
  [2, 1, 3, 2, 1, 2], [2, 2, 3, 1, 1, 2], [3, 1, 2, 1, 3, 1],
    [3, 1, 1, 2, 2, 2], [3, 2, 1, 1, 2, 2], // 25
  [3, 2, 1, 2, 2, 1], [3, 1, 2, 2, 1, 2], [3, 2, 2, 1, 1, 2],
    [3, 2, 2, 2, 1, 1], [2, 1, 2, 1, 2, 3], // 30
  [2, 1, 2, 3, 2, 1], [2, 3, 2, 1, 2, 1], [1, 1, 1, 3, 2, 3],
    [1, 3, 1, 1, 2, 3], [1, 3, 1, 3, 2, 1], // 35
  [1, 1, 2, 3, 1, 3], [1, 3, 2, 1, 1, 3], [1, 3, 2, 3, 1, 1],
    [2, 1, 1, 3, 1, 3], [2, 3, 1, 1, 1, 3], // 40
  [2, 3, 1, 3, 1, 1], [1, 1, 2, 1, 3, 3], [1, 1, 2, 3, 3, 1],
    [1, 3, 2, 1, 3, 1], [1, 1, 3, 1, 2, 3], // 45
  [1, 1, 3, 3, 2, 1], [1, 3, 3, 1, 2, 1], [3, 1, 3, 1, 2, 1],
    [2, 1, 1, 3, 3, 1], [2, 3, 1, 1, 3, 1], // 50
  [2, 1, 3, 1, 1, 3], [2, 1, 3, 3, 1, 1], [2, 1, 3, 1, 3, 1],
    [3, 1, 1, 1, 2, 3], [3, 1, 1, 3, 2, 1], // 55
  [3, 3, 1, 1, 2, 1], [3, 1, 2, 1, 1, 3], [3, 1, 2, 3, 1, 1],
    [3, 3, 2, 1, 1, 1], [3, 1, 4, 1, 1, 1], // 60
  [2, 2, 1, 4, 1, 1], [4, 3, 1, 1, 1, 1], [1, 1, 1, 2, 2, 4],
    [1, 1, 1, 4, 2, 2], [1, 2, 1, 1, 2, 4], // 65
  [1, 2, 1, 4, 2, 1], [1, 4, 1, 1, 2, 2], [1, 4, 1, 2, 2, 1],
    [1, 1, 2, 2, 1, 4], [1, 1, 2, 4, 1, 2], // 70
  [1, 2, 2, 1, 1, 4], [1, 2, 2, 4, 1, 1], [1, 4, 2, 1, 1, 2],
    [1, 4, 2, 2, 1, 1], [2, 4, 1, 2, 1, 1], // 75
  [2, 2, 1, 1, 1, 4], [4, 1, 3, 1, 1, 1], [2, 4, 1, 1, 1, 2],
    [1, 3, 4, 1, 1, 1], [1, 1, 1, 2, 4, 2], // 80
  [1, 2, 1, 1, 4, 2], [1, 2, 1, 2, 4, 1], [1, 1, 4, 2, 1, 2],
    [1, 2, 4, 1, 1, 2], [1, 2, 4, 2, 1, 1], // 85
  [4, 1, 1, 2, 1, 2], [4, 2, 1, 1, 1, 2], [4, 2, 1, 2, 1, 1],
    [2, 1, 2, 1, 4, 1], [2, 1, 4, 1, 2, 1], // 90
  [4, 1, 2, 1, 2, 1], [1, 1, 1, 1, 4, 3], [1, 1, 1, 3, 4, 1],
    [1, 3, 1, 1, 4, 1], [1, 1, 4, 1, 1, 3], // 95
  [1, 1, 4, 3, 1, 1], [4, 1, 1, 1, 1, 3], [4, 1, 1, 3, 1, 1],
    [1, 1, 3, 1, 4, 1], [1, 1, 4, 1, 3, 1], // 100
  [3, 1, 1, 1, 4, 1], [4, 1, 1, 1, 3, 1], [2, 1, 1, 4, 1, 2],
    [2, 1, 1, 2, 1, 4], [2, 1, 1, 2, 3, 2], // 105
  [2, 3, 3, 1, 1, 1, 2]];
 


ich habe das folgendermassen versucht aufzulösen

Code: Alles auswählen

 
type
  TArrayInteger = TArray<Integer>;
 
var
  CODE_PATTERNS: TArray<{$IFDEF FPC}TArrayInteger{$ELSE}TArray<Integer>{$ENDIF}>;
.........
  CODE_PATTERNS :=  [[2, 1, 2, 2, 2, 2], // 0           //<<---- ZXing.OneD.Code128Reader.pas(102,29) Error: range check error in set constructor or duplicate set element
  [2, 2, 2, 1, 2, 2], [2, 2, 2, 2, 2, 1], [1, 2, 1, 2, 2, 3],
    [1, 2, 1, 3, 2, 2], [1, 3, 1, 2, 2, 2], // 5
  [1, 2, 2, 2, 1, 3], [1, 2, 2, 3, 1, 2], [1, 3, 2, 2, 1, 2], ......
 

Nur die Zuweisung des Arrays mit Zahlen zu der Variablen CODE_PATTERNS will nicht funktionieren.

Ist die Defintion TArray<TArray<Integer>>; nicht ident mit array[][] of integer; ?

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von marcov »

Das ist eine sehr neue (XE7) syntax.

Ein etwas andere, ältere Syntax (code_patterns:=TArrayInteger.create(1,2,3); )wird glaub ich unterstützt in Trunk. Ich weiss nicht ob da auch multidimensionale Varianten von sind. Ich benutze diese syntax nicht, nutzte noch immer normaler Declaration mit ein CONST block.

Mathias
Beiträge: 6162
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von Mathias »

Wen ich das so lese, müsste die funktionieren, tut es aber nicht.

Code: Alles auswählen

var
  a: TArray<byte>;
  aa: array[0..2] of byte;
begin
  a := [1, 2, 3];
  aa := [1, 2, 3];


Oder ist die XE7 vorbehalten ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

Es ist nicht nur Multidimensional, sondern sie Einträge sind auch unterschiedlich lange in einer Dimension. Damit geht der Const-Block nicht.

Code: Alles auswählen

[2, 1, 2, 2, 2, 2],......,[2, 3, 3, 1, 1, 1, 2] 


So gesehen macht das TArray<TArray<Integer>> schon Sinn.

Mal sehen ob ich auf eine Lösung komme, kann ja auch ein array [0..134] of TArray<Integer> werden. Ich muß nur sehen, wie ich die Konstanten dann hineinbringe.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6162
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von Mathias »

Es ist nicht nur Multidimensional, sondern sie Einträge sind auch unterschiedlich lange in einer Dimension.

Da müsste sicher noch ein SetLength(... rein.

Das ist ausnahmsweise eine Sache, wo C++ an FPC überlegen ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von af0815 »

Mathias hat geschrieben:Wen ich das so lese, müsste die funktionieren, tut es aber nicht.

Code: Alles auswählen

var
  a: TArray<byte>;
  aa: array[0..2] of byte;
begin
  a := [1, 2, 3];
  aa := [1, 2, 3];


Oder ist die XE7 vorbehalten ?

Das geht

Code: Alles auswählen

  Numbers : array [1..3] of Integer = (1, 2, 3);
 
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6162
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von Mathias »

Das geht

Code: Alles auswählen

  Numbers : array [1..3] of Integer = (1, 2, 3)


Dies schon, aber ich meinte zu Laufzeit.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von marcov »

Mathias hat geschrieben:
Das geht

Code: Alles auswählen

  Numbers : array [1..3] of Integer = (1, 2, 3)


Dies schon, aber ich meinte zu Laufzeit.


Code: Alles auswählen

a:=numbers;


:twisted:

Mathias
Beiträge: 6162
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von Mathias »

Die 2. Variante würde doch viel eleganter aussehen oder ?

Code: Alles auswählen

procedure TMatrix.Identity;
const
  m: Tmat4x4 = ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0));
begin
  FMatrix := m;
end


Code: Alles auswählen

procedure TMatrix.Identity;
begin
  FMatrix := ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0));
end
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Generics Delphi <-> Lazarus/FPC Umwandlung

Beitrag von marcov »

Mathias hat geschrieben:Die 2. Variante würde doch viel eleganter aussehen oder ?


Vielleicht wenn man eine Sprache neu entwickeln würde. Aber wie oft nutzt man das wirklich? Einfacher keine Exoten im Dialekt zu nutzen, die sehr geringe Vorteilen wiegen nicht auf gegen den Ärger es umschreiben zu müssen.

Antworten