Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3 (https://www.delphipraxis.net/214054-delphi-12-tlist-unter-64-bit-funktioniert-nicht-mehr-wie-unter-11-3-a.html)

swestner 10. Nov 2023 13:06

Delphi-Version: 11 Alexandria

Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Hallo,

folgender Code hat mit Delphi 11.3 unter 32 und 64 Bit problemlos compiliert. Mit Delphi 12 32 Bit funktioniert es weiterhin, mit Delphi 12 64 Bit gibt es Fehler:

Delphi-Quellcode:
type TSupBookList = class(TList)
private
     function GetItems(Index: integer): TSupBook;
public
     destructor Destroy; override;
     procedure Clear; override;
     procedure Add(P: PRecSUPBOOK); overload;
     procedure Add(Path,Filename,SheetName: AxUCString); overload;
     function AddEncodec(Tabs: integer; Code: word): integer;
     property Items[Index: integer]: TSupBook read GetItems; default;
end;

type TExternalNames = class(TObject)
private
     FSupBooks: TSupBookList;
public
     procedure SetCRN        (SheetIndex: integer; P: PRecCRN; Size: word);
end;

procedure TExternalNames.SetCRN(SheetIndex: integer; P: PRecCRN; Size: word);
begin
  if FSupBooks.Count <= 0 then
    raise XLSRWException.Create('No SUPBOOK for CRN');
  if SheetIndex >= FSupBooks[FSupBooks.Count - 1].Count then   // <----E2018 Record, object or class type required
    raise XLSRWException.Create('Invalid SUPBOOK Sheet Index');
  FSupBooks[FSupBooks.Count - 1].Sheets[SheetIndex].SetCRN(P,Size); // <----E2018 Record, object or class type required
end;
Wo ist da jetzt das Problem? Zumal alles mit 11.3 funktioniert hat.

Wurde in 12 was an TList geändert?

Grüße

Stefan Westner

Uwe Raabe 10. Nov 2023 13:12

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von swestner (Beitrag 1529430)
Wurde in 12 was a TList geändert?

Delphi-Quellcode:
Index
und
Delphi-Quellcode:
Count
sind jetzt
Delphi-Quellcode:
NativeInt
, was unter 64-Bit nicht mehr gleich
Delphi-Quellcode:
Integer
ist. Damit löst
Delphi-Quellcode:
FSupBooks[FSupBooks.Count - 1]
auf das NativeInt
Delphi-Quellcode:
Items
Property von
Delphi-Quellcode:
TList
auf und nicht auf deine Integer Version.

swestner 10. Nov 2023 14:30

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Heißt das jetzt, daß ich überall machen muß:

Delphi-Quellcode:
{$IFDEF WIN32}
property Items[Index: integer]: TSupBook read GetItems; default;
{$ELSEIF WIN64}
property Items[Index: NativeInt]: TSupBook read GetItems; default;
{$ENDIF}
Oder kann pauschal immer

Delphi-Quellcode:
property Items[Index: NativeInt]: TSupBook read GetItems; default;

verwendet werden?

himitsu 10. Nov 2023 14:47

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
NativeInt ist unter 32 Bit 32 Bit groß und unter 64 Bit natürlich 64 Bit.

im Grunde genommen sieht es quasi so aus
Delphi-Quellcode:
type
  {$IFDEF WIN32}
  NativeInt = Integer; // aka Int32
  {$ELSE}
  NativeInt = Int64;
  {$ENDIF}
https://quality.embarcadero.com/browse/RSP-20886
https://quality.embarcadero.com/browse/RSP-42722
https://www.facebook.com/embarcadero...h7JYZD1KTBhKKl

Es gab aber im QP auch einen eigenen BugReport bezüglich dieses Problems (fand ihn nicht, aber siehe Facebook),
also dass der Typ "NativeInt" nun strenger geprüft wird
und unter Win64 dann plötzlich Int64 und NativeInt nicht "identisch" sind, obwohl sie eigentlich gleich sind.

Uwe Raabe 10. Nov 2023 14:50

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von swestner (Beitrag 1529439)
Oder kann pauschal immer

property Items[Index: NativeInt]: TSupBook read GetItems; default;

verwendet werden?

Genau so ist das gedacht.

Achim Kalwa 18. Jun 2024 10:47

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1529443)
Zitat:

Zitat von swestner (Beitrag 1529439)
Oder kann pauschal immer

property Items[Index: NativeInt]: TSupBook read GetItems; default;

verwendet werden?

Genau so ist das gedacht.

Sorry für das Aufwärmen eines alten Threads:
Gibt es eine abwärtskompatible Lösung? Wir stellen gerade von D11.3 auf D12.1 um und sind dabei auf obige Problematik bei Win64 gestoßen. Gibt es eine Lösung, die sowohl mit D11 als D12 funktioniert? Bei D11 ist ja TList (bzw. TObjectList).Items[Index: Integer] deklariert; und bei D12 als NativeInt.

Wie weiter oben schon vorgeschlagen könnte ich mittels {$IFDEF WIN32} type NativeInt = Integer;{$ENDIF} einbauen; aber an manchen Stellen wie z.B. der Windows-API wird dann noch wieder der "echte" NativeInt verwendet.

TIA
Achim

Uwe Raabe 18. Jun 2024 10:53

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Bei welchem Code habt ihr denn Probleme?

Achim Kalwa 18. Jun 2024 12:22

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1537891)
Bei welchem Code habt ihr denn Probleme?

Im Grunde so wie oben im 1. Beitrag schon beschrieben; hier mal mein Beispiel:
Delphi-Quellcode:
uses
  ..., Contnrs;
type
  TBauteil = class(TObject)
    ID  : Integer;
    Name : string;
  end;

  TBauteilList = class(TObjectList)
  private
    function GetItem(ndx: Integer): TBauteil;
  public
    property Items[ndx: Integer]: TBauteil read GetItem; default;
  end;

{ TBauteilList }

function TBauteilList.GetItem(ndx: Integer): TBauteil;
begin
  Result := TBauteil(inherited Items[ndx]);
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  LBauteilList : TBauteilList;
  LBauteil1    : TBauteil;
  LBauteil2    : TBauteil;
  i           : Integer; { 3 }
begin
  LBauteilList := TBauteilList.Create(True);
  try
    for i := 0 to LBauteilList.Count-1 do
    begin
      LBauteil1 := LBauteilList[i];                   { 1 }
      LBauteil2 := LBauteilList[LBauteilList.Count-1]; { 2 }

      if Assigned(LBauteil1) and Assigned(LBauteil2) then ;
    end;
  finally
    LBauteilList.Free;
  end;
end;
(Ja, die Liste ist leer. Aber es geht um einen Fehler beim compilieren für Win64.)

Delphi 11.3: compiliert ohne Fehler.
Delphi 12.1: In der mit { 2 } markierten Zeile "E2010 Incompatible types: 'TBauteil' and 'TObject'"

Tausche ich in der Klasse TBauteilList den Datentyp für ndx in "NativeInt", dann dreht sich das Verhalten um:

Delphi 11.3: In der mit { 1 } markierten Zeile: "E2010 Incompatible types: 'TBauteil' and 'TObject'"
Delphi 12.1: compiliert ohne Fehler.

Nächster Versuch:
Die Laufvariable "i" (Markierung { 3 }) ändern von Integer nach NativeInt:

Delphi 11.3: Fehler in der Zeile { 2 }
Delphi 12.2: kein Fehler.

Gibt es eine allgemeingültige Lösung?
Von dieser Art Listen -- von TObjectList abgeleitet -- haben wir jede Menge.

Gruß

freimatz 18. Jun 2024 13:13

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Warum nehmt Ihr nicht TObjectList<TBauteil>?

Achim Kalwa 18. Jun 2024 13:23

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von freimatz (Beitrag 1537905)
Warum nehmt Ihr nicht TObjectList<TBauteil>?

Historisch gewachsener Code seit Delphi 3; über 100 Listen-Klassen müssten umgebaut werden. Damals gab's die Generics noch nicht.

Uwe Raabe 18. Jun 2024 13:41

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Wie wäre es denn damit:
Delphi-Quellcode:
type
{$IF CompilerVersion < 36.0 Delphi 12 Athens }
  TListIndex = Integer;
{$ELSE}
  TListIndex = NativeInt;
{$ENDIF}

type
  TBauteil = class(TObject)
    ID : Integer;
    Name : string;
  end;

  TBauteilList = class(TObjectList)
  private
    function GetItem(ndx: TListIndex): TBauteil;
  public
    property Items[ndx: TListIndex]: TBauteil read GetItem; default;
  end;

Klaus01 18. Jun 2024 13:59

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
.. wenn Du
Delphi-Quellcode:
LBauteil2 := TBauteil(LBauteilList[LBauteilList.Count-1]); { 2 }
sollte es bei beiden Varianten funktionieren.
Warum bei NativeInt ein Cast ( in Delph 11.3) notwendig ist - entzieht sich meiner Kenntnis.

Grüße
Klaus

himitsu 18. Jun 2024 14:27

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Delphi prüft/vergleicht jetzt auch Alias-Deklarationen stärker.

Delphi-Quellcode:
type
  MyInt1 = Integer;
  MyInt2 = type Integer;
Früher war MyInt1 und Integer das "Gleiche" ... jetzt eventuell nicht mehr.

z.B. auch im CodeInsight und der CodeCompletion zu sehen, wo du beim SendMessage jetzt LPARAM und WPARAM als Typen siehst, und nicht mehr Integer (Win32).

Und bezüglch NativeInt wurde früher in Win32 es überall als "Integer" angezeigt ... jetzt als "NativeInt".
In Win64 wurde NativeInt früher als irgenwas wie Int64 (weiß nicht genau) und jetzt ebenfalls als NativeInt.

Aus Sicht des Laufzeitcodes ist es nicht verständlich,
aber aus Sicht des Entwicklers ist es eigentlich schön (wobei des nett wäre, wenn beides gezeigt würde ... wie die Deklaration ist und was "wirklich" der Typ ist)

Uwe Raabe 18. Jun 2024 14:59

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von Klaus01 (Beitrag 1537917)
Warum bei NativeInt ein Cast ( in Delph 11.3) notwendig ist - entzieht sich meiner Kenntnis.

Das default Items in TObjectList ist mit NativeInt als Index deklariert. Die Items Deklaration in TBauteilList überschreibt das nicht etwa, sondern wird als override Property interpretiert. Je nach Compiler und Typ des übergebenen Index wird nun die Variante mit Index oder die mit NativeInt verwendet.
Delphi-Quellcode:
      LBauteil1 := LBauteilList[i]; { 1 }
      LBauteil2 := LBauteilList[LBauteilList.Count-1]; { 2 }
In {1} wird ein Integer übergeben, was auf die Deklaration in TBauteilList.Items aufgelöst wird. In {2} is LBauteilList.Count aber ein NativeInt, was bei der Subtraktion erhalten bleibt. Das wird dann unter Win64 auf TObjektList.Items aufgelöst und führt zu dem Incompatible Types Fehler.

jaenicke 18. Jun 2024 15:09

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von Achim Kalwa (Beitrag 1537908)
Zitat:

Zitat von freimatz (Beitrag 1537905)
Warum nehmt Ihr nicht TObjectList<TBauteil>?

Historisch gewachsener Code seit Delphi 3; über 100 Listen-Klassen müssten umgebaut werden. Damals gab's die Generics noch nicht.

Damals konnte mal so etwas mit Include-Files übrigens trotzdem hinbekommen. Als dann Generics kamen, konnte ich das dann per ifdef direkt umbiegen, so dass es keine großén Änderungen gab.

Angesichts dessen, dass ja ohnehin etwas geändert werden muss, stellt sich aber hier denke ich schon die Frage, ob ein Umbau auf Generics nicht die sinnvollere Lösung wäre. Denn die Änderungen sollten sich ja auf die Klassen beschränken, die Nutzung sollte ja gleich bleiben. Bevor man da ggf. irgendwann noch einmal ran muss...

Achim Kalwa 18. Jun 2024 17:11

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
[QUOTE=Uwe Raabe;1537913]Wie wäre es denn damit:
Delphi-Quellcode:
type
{$IF CompilerVersion < 36.0 Delphi 12 Athens }
  TListIndex = Integer;
{$ELSE}
  TListIndex = NativeInt;
{$ENDIF}
Genau diese Idee hatte ich auch schon. Der Anpassungsaufwand ist aber enorm; ich muss ja nicht nur die jeweiligen List-Klassen anpassen; sondern überall im Code auch die Index-Variablen.

Achim Kalwa 18. Jun 2024 17:15

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von jaenicke (Beitrag 1537929)
Angesichts dessen, dass ja ohnehin etwas geändert werden muss, stellt sich aber hier denke ich schon die Frage, ob ein Umbau auf Generics nicht die sinnvollere Lösung wäre. Denn die Änderungen sollten sich ja auf die Klassen beschränken, die Nutzung sollte ja gleich bleiben. Bevor man da ggf. irgendwann noch einmal ran muss...

Ein gutes Argument; Danke!
Kannst Du auch noch erklären, warum das Problem bei TBauteilList = TObjectList<TBauteil> nicht auftritt, auch wenn meine Index-Variable vom Typ "Integer" ist...

jaenicke 18. Jun 2024 17:51

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von Achim Kalwa (Beitrag 1537934)
Kannst Du auch noch erklären, warum das Problem bei TBauteilList = TObjectList<TBauteil> nicht auftritt, auch wenn meine Index-Variable vom Typ "Integer" ist...

Das Problem war ja, dass nicht dein typisierter Getter / Items verwendet wurde, du also ein TObject bekommen hast. Wenn der Original-Getter / Items nun den korrekten Typ liefern, passt alles.

Achim Kalwa 18. Jun 2024 18:00

AW: Delphi 12 / TList unter 64 Bit funktioniert nicht mehr wie unter 11.3
 
Zitat:

Zitat von jaenicke (Beitrag 1537937)
Wenn der Original-Getter / Items nun den korrekten Typ liefern, passt alles.

:thumb: Ja klar; jetzt wo Du es sagst...
Dann werde ich wohl die Generics einsetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz