[Gelöst] Casting TObject zu Integer funktioniert nicht.

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

[Gelöst] Casting TObject zu Integer funktioniert nicht.

Beitragvon kirchfritz » 5. Feb 2018, 08:44 [Gelöst] Casting TObject zu Integer funktioniert nicht.

Kann mir mal jemand erklären warum der Sourcecode meines Minimalprojects nicht mehr funktioniert:

Code: Alles auswählen
program Project1;
 
{$mode objfpc}{$H+}
 
uses
  Classes;
 
var
  sl : TStringList;
  i : integer;
 
begin
  sl := TStringList.create;
  with sl do
  begin
    Clear;
    AddObject('hello', TObject(1));
    AddObject('in', TObject(2));
    AddObject('there', TObject(3));
  end;
  for i := 0 to sl.Count - 1 do
  begin
    writeln(integer(sl.Objects[i]));
  end;
  sl.Free;
end.
 

Bei der Writeln Anweisung kommt als Fehlermeldung:
Code: Alles auswählen
Error illegal type conversion from TObject to LongInt


Das hat bei mir immer funktioniert, aber seit dem Umstieg auf Lazarus 1.8 und damit auf FPC 3.0.4 geht das irgendwie nicht mehr.
Hat irgendjemand eine Idee, was da bei mir falsch läuft?

Für Eure Hilfe wäre ich sehr dankbar.
Fritz
Zuletzt geändert von kirchfritz am 5. Feb 2018, 09:46, insgesamt 1-mal geändert.
kirchfritz
 
Beiträge: 49
Registriert: 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 1.7 FPC 3.1.1) | 
CPU-Target: 32Bit
Nach oben

Beitragvon theo » 5. Feb 2018, 08:52 Re: Casting TObject zu Integer funktioniert nicht. Warum?

theo
 
Beiträge: 8051
Registriert: 11. Sep 2006, 18:01

Beitragvon mse » 5. Feb 2018, 08:57 Re: Casting TObject zu Integer funktioniert nicht. Warum?

kirchfritz hat geschrieben:Kann mir mal jemand erklären warum der Sourcecode meines Minimalprojects nicht mehr funktioniert:

Weil du vielleicht auf 64 bit gewechselt bist. pointer (64bit) ist nicht mehr mit integer(32bit) kompatibel.
Code: Alles auswählen
 
  for i := 0 to sl.Count - 1 do
  begin
   writeln(ptrint(sl.Objects[i]));
  end;
 
mse
 
Beiträge: 1948
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon kirchfritz » 5. Feb 2018, 09:45 [Gelöst] Casting TObject zu Integer funktioniert nicht. Waru

Danke mse, Danke theo,

in leichter Abwandlung funktioniert 's jetzt

Code: Alles auswählen
program Project1;
 
{$mode objfpc}{$H+}
 
uses
  Classes;
 
var
  sl : TStringList;
  i : Qword;
begin
  sl := TStringList.create;
  with sl do
  begin
    Clear;
    i := 1;
    AddObject('hello', TObject(i));
    i := 2;
    AddObject('in', TObject(i));
    i := 3;
    AddObject('there', TObject(i));
  end;
  for i := 0 to sl.Count - 1 do
  begin
    writeln(PtrInt(sl.Objects[i]));
  end;
  sl.Free;
end.
 


Für alle, die diesen Beitrag später mal lesen sollten:
Wichtig ist, dass die Variable i vom Type QWord ist und die Writeln-Anweisung das Casting mit PtrInt macht.
kirchfritz
 
Beiträge: 49
Registriert: 3. Jan 2011, 13:34
OS, Lazarus, FPC: Win10 (L 1.7 FPC 3.1.1) | 
CPU-Target: 32Bit
Nach oben

Beitragvon theo » 5. Feb 2018, 10:12 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

@kirchfritz, mse: Warum nicht den von mir vorgeschlagenen PtrUInt?
Was soll ein vorzeichenbehafteter Typ bei einem Pointer?
Ptrint is considered harmfull and should almost never be used in actual code, because pointers are normally unsigned.

https://www.freepascal.org/docs-html/rt ... trint.html
theo
 
Beiträge: 8051
Registriert: 11. Sep 2006, 18:01

Beitragvon m.fuchs » 5. Feb 2018, 12:08 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

Darf ich dir auch noch eine Variante zeigen, die ganz ohne missbräuchlichem Cast auskommt?

Code: Alles auswählen
program Project1;
{$MODE ObjFpc}
{$H+}
 
uses
  Classes, SysUtils, Fgl;
 
type
  TStringIntegerMap = specialize TFPGMap<String, Integer>;
 
var
  Map: TStringIntegerMap;
  i: Integer;
 
begin
  Map := TStringIntegerMap.Create;
  Map.Clear;
  Map.Add('hello', 1);
  Map.Add('in', 2);
  Map.Add('there', 3);
  for i := 0 to Map.Count - 1 do begin
    WriteLn(Map.Data[i]);
  end;
  FreeAndNil(Map);
end.     
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
m.fuchs
 
Beiträge: 1959
Registriert: 22. Sep 2006, 18:32
Wohnort: Berlin
OS, Lazarus, FPC: Winux (L 1.8.4, FPC 3.0.4) | 
CPU-Target: x86, x64, arm
Nach oben

Beitragvon Mathias » 5. Feb 2018, 18:14 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

Für was wird AddObjects gebraucht ?
Ist dies zum durchnummerieren der einzelnen Stringeinträge ?
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 4107
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon mse » 6. Feb 2018, 07:58 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

theo hat geschrieben:@kirchfritz, mse: Warum nicht den von mir vorgeschlagenen PtrUInt?

Um eine integer in einem pointer zu speichern ist ptrint der geeignete Typ.
Um eine cardinal in einem pointer zu speichern ist ptruint der geeignete Typ.
Zuletzt geändert von mse am 6. Feb 2018, 11:17, insgesamt 1-mal geändert.
mse
 
Beiträge: 1948
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon af0815 » 6. Feb 2018, 10:41 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

mse hat geschrieben:Um eine integer in einem pointer zu speichern ist ptrint der geeignete Typ.
Um eine cardinal in einem pointer zu speichern ist ptuint der geeignete Typ.

Zu meinem Verständnis - müsste man genaugenommen nicht den Integer/Cardinal/... mit Boxing und Unboxing behandeln (=ein Objekt daraus machen) damit ist entsprechend sicher ist und auch auf den verschiedenen Plattformen arbeitet ist ?! Weil hier ist man ja ansonsten IMHO Plattformabhängig.


Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3412
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: Win7/Linux (L stable FPC stable) per fpcup | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon mse » 6. Feb 2018, 11:20 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

Ich glaube nicht. Die Bit-Grössen von integer/cardinal sind immer <= Bit-Grösse von pointer.
mse
 
Beiträge: 1948
Registriert: 16. Okt 2008, 09:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0) | 
CPU-Target: x86,x64,ARM
Nach oben

Beitragvon kupferstecher » 6. Feb 2018, 13:03 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

theo hat geschrieben:@kirchfritz, mse: Warum nicht den von mir vorgeschlagenen PtrUInt?
Was soll ein vorzeichenbehafteter Typ bei einem Pointer?
Ptrint is considered harmfull and should almost never be used in actual code, because pointers are normally unsigned.


Zum Beispiel bei PostMessage wird als Argument für WParam und LParam ein PtrInt erwartet.
Was würde passieren, wenn man aber auf PtrUInt castet? Kompilieren tut es zumindest.
Und was kann passieren, wenn man auf Ptrint castet, in Fällen wo PtrUInt erwartet wird?
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

Beitragvon theo » 6. Feb 2018, 17:08 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

kupferstecher hat geschrieben:
theo hat geschrieben:@kirchfritz, mse: Warum nicht den von mir vorgeschlagenen PtrUInt?
Was soll ein vorzeichenbehafteter Typ bei einem Pointer?
Ptrint is considered harmfull and should almost never be used in actual code, because pointers are normally unsigned.


Zum Beispiel bei PostMessage wird als Argument für WParam und LParam ein PtrInt erwartet.
Was würde passieren, wenn man aber auf PtrUInt castet? Kompilieren tut es zumindest.
Und was kann passieren, wenn man auf Ptrint castet, in Fällen wo PtrUInt erwartet wird?


"Harmful" heißt in diesem Falle mMn nicht, dass etwas in die Hose gehen muss, aber du musst einfach ganz genau wissen was du tust. Wie bei Assembler o.ä.
theo
 
Beiträge: 8051
Registriert: 11. Sep 2006, 18:01

Beitragvon kupferstecher » 7. Feb 2018, 00:36 Re: [Gelöst] Casting TObject zu Integer funktioniert nicht.

Mir geht es darum, was überhaupt passieren kann.

Ich hab mir angeschaut, was herauskommt, wenn man eine uInt8 (Byte) mit dem Wert $FF auf Int8 castet, das Ergebnis ist -1. Soweit so klar, aber auch über eine Zuweisung kommt das gleiche Ergebnis raus. In die andere Richtung von Int8 auf uInt8 kommt wieder $FF heraus, sowohl beim casten als auch über eine Zuweisung. D.h. das Vorzeichen beschädigt nicht das Bitmuster. Für den Anwendungsfall dass eine Bibliothek einen Pointer per Integer oder Unsigned erwartet, wäre es also erstmal egal, ob man per ptrInt oder ptrUInt castet.

Dann gäbe es noch den Fall, dass man Adressen berechnen möchte (Arrays etc.). Aber auch dort wandelt man ja nach erfolgter Berechnung wieder in einen Pointer um, es ist also wieder nur das Bitmuster entscheidend.
kupferstecher
 
Beiträge: 142
Registriert: 17. Nov 2016, 11:52

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried