C/C++ enum in Pascal

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6964
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

C/C++ enum in Pascal

Beitrag von Mathias »

Ist so etwas auch mit Pascal möglich ?

Code: Alles auswählen

enum KeyPressSurfaces {
	KEY_PRESS_SURFACE_DEFAULT,
	KEY_PRESS_SURFACE_UP,
	KEY_PRESS_SURFACE_DOWN,
	KEY_PRESS_SURFACE_LEFT,
	KEY_PRESS_SURFACE_RIGHT,
	KEY_PRESS_SURFACE_TOTAL};
	
SDL_Surface* gKeyPressSurfaces[ KEY_PRESS_SURFACE_TOTAL ];	
Der Zugriff später erfolgt so:

Code: Alles auswählen

	gCurrentSurface = gKeyPressSurfaces[ KEY_PRESS_SURFACE_UP ];
Ich habe folgendes probiert, aber ohne Erfolg:

Code: Alles auswählen

  KeyPressesSurface: set of (KEY_PRESS_SURFACE_DEFAULT, KEY_PRESS_SURFACE_UP, KEY_PRESS_SURFACE_DOWN, KEY_PRESS_SURFACE_LEFT, KEY_PRESS_SURFACE_RIGHT, KEY_PRESS_SURFACE_TOTAL);
  gKeyPressSurfaces:array [0..KEY_PRESS_SURFACE_TOTAL-1]of PSDL_Surface;  
Es kommt nur "Error: Incompatible types: got "<enumeration type>" expected "Int64""

Der einzige weg sehe ich momentan so:

Code: Alles auswählen

const
	KEY_PRESS_SURFACE_DEFAULT = 0;
	KEY_PRESS_SURFACE_UP = 1;
	KEY_PRESS_SURFACE_DOWN = 2;
	KEY_PRESS_SURFACE_LEFT = 3;
	KEY_PRESS_SURFACE_RIGHT = 4;
	KEY_PRESS_SURFACE_TOTAL = 5;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: C/C++ enum in Pascal

Beitrag von theo »

Hatte mal kürzlich einen Frage im Bugtracker gestellt zu dem Thema.
Dort siehst du zwei Möglichkeiten.
https://gitlab.com/freepascal.org/lazar ... sues/39988
Aber frag mich nicht... :wink:

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: C/C++ enum in Pascal

Beitrag von Winni »

Hi!

Definier doch erstmal den Enum Type:

Code: Alles auswählen

Type
TKeyPressSurfaces =(
	KEY_PRESS_SURFACE_DEFAULT,
	KEY_PRESS_SURFACE_UP,
	KEY_PRESS_SURFACE_DOWN,
	KEY_PRESS_SURFACE_LEFT,
	KEY_PRESS_SURFACE_RIGHT,
	KEY_PRESS_SURFACE_TOTAL);
Dann das Set und das Array:

Code: Alles auswählen

Type
  TKeyPressesSet: set of TKeyPressSurfaces;
  TKeyPressArray:array [TKeyPressSurfaces] of PSDL_Surface;

Einfach mal drann gewöhnen, das Pascal nicht C++ ist.
Sonst kommt es eben zu den Fehlern, wenn man versucht C++ nachzuplappern.

Und selbstdefinierte Typen fangen mit "T" an.

Winni

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

Re: C/C++ enum in Pascal

Beitrag von Mathias »

@Winni
Danke, dies hat schon mal weiter geholfen.

Nur das Aufräumen sieht etwas komisch aus. Elegant nur mit "i" geht es leider nicht.

Code: Alles auswählen

    for i := 0 to Length(gKeyPressSurfaces) - 1 do begin
      SDL_FreeSurface(gKeyPressSurfaces[TKeyPressesSurface(i)]);
    end;
Da kann man fast besser einen Record nehmen, auch wen man die Elemente beim Aufräumen einzeln ansprechen muss.
Beim Initialisieren und bei der Abfrage ist es jetzt schon einzeln.

Oder kennt einer noch etwas eleganteres ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: C/C++ enum in Pascal

Beitrag von Winni »

Hi!

Code: Alles auswählen

var e: TKeyPressesSurfaces;

For e := low(TKeyPressesSurfaces) to high(TKeyPressesSurfaces) do
    SDL_FreeSurface(gKeyPressSurfaces[e]);
Pascal kann wesentlich eleganter sein, als die Sprachen mit geschweiften Klammern.

Winni

PascalDragon
Beiträge: 963
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: C/C++ enum in Pascal

Beitrag von PascalDragon »

Noch einfacher:

Code: Alles auswählen

var
  surface: PSDL_Surface;
// ...
  for surface in gKeyPressSurfaces do
    SDL_FreeSurface(surface);
FPC Compiler Entwickler

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: C/C++ enum in Pascal

Beitrag von Winni »

PascalDragon hat geschrieben: Mi 18. Jan 2023, 23:01 Noch einfacher:
Sehr gut!

Irgendwann gewöhn ich mich auch noch an den "neumodischen Kram".

Winni

Warf
Beiträge: 2146
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: C/C++ enum in Pascal

Beitrag von Warf »

Kurz zur Erläuterung, C Enums sind was komplett anderes als Pascal enums, in C ein ENUM ist nichts anderes als eine Reihe von Konstanten des Typs int (tatsächlich die einzige echte Form von konstanten die es in C überhaupt gibt)

Beispiel:

Code: Alles auswählen

enum Test {A, B, C};
Ist equivalenz zu dem Pascal code

Code: Alles auswählen

const A = 0;
const B = 1;
const C =2;
Von daher ist deine ursprüngliche lösung tatsächlich das echte C equivalenz.

Pascal enums im gegensatz dazu sind echte eigene typen und benötigen daher explizites konvertieren

Code: Alles auswählen

TTest = (A, B, C);
Ord(A) = 0
TTest(0) = A

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

Re: C/C++ enum in Pascal

Beitrag von Mathias »

PascalDragon hat geschrieben: Mi 18. Jan 2023, 23:01 Noch einfacher:

Code: Alles auswählen

var
  surface: PSDL_Surface;
// ...
  for surface in gKeyPressSurfaces do
    SDL_FreeSurface(surface);
Coole Funktion. Einziges Manke, man kann der Variable nichts zuordnen.

Code: Alles auswählen

    for surface in gKeyPressSurfaces do begin
      SDL_FreeSurface(surface);
      surface := nil;  // Geht nicht
    end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 963
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: C/C++ enum in Pascal

Beitrag von PascalDragon »

Mathias hat geschrieben: Do 19. Jan 2023, 17:46 Coole Funktion. Einziges Manke, man kann der Variable nichts zuordnen.

Code: Alles auswählen

    for surface in gKeyPressSurfaces do begin
      SDL_FreeSurface(surface);
      surface := nil;  // Geht nicht
    end;
Das ist korrekt und auch so Absicht. Da du allerdings alle Einträge löscht kannst du genauso am Schluss folgendes machen:

Code: Alles auswählen

FillChar(gKeyPressSurfaces, SizeOf(gKeyPressSurfaces), #0)
FPC Compiler Entwickler

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

Re: C/C++ enum in Pascal

Beitrag von Mathias »

Bei Pascal Enums kann man die Werte vorbelegen.

Dies sieht dann so aus.

Code: Alles auswählen

type
  Tcommand = (cmPlay := 1000, cmNext = 1001);     
Nun das interessante es wird kompiliert, obwohl einmal ":=" steht und beim anderen nur ein "=".

Das Wiki kann sich auch nicht für eine Variante entscheiden, wen man diese beiden Beträge vergleicht.
https://wiki.freepascal.org/Enum_Type/de
https://wiki.freepascal.org/Enum_type
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 963
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: C/C++ enum in Pascal

Beitrag von PascalDragon »

Mathias hat geschrieben: Mo 1. Jul 2024, 17:50 Nun das interessante es wird kompiliert, obwohl einmal ":=" steht und beim anderen nur ein "=".
Die Variante mit dem = kommt von Delphi, die andere aus FPC's Vergangenheit (bevor Delphi dies unterstützt hatte). Es werden einfach weiterhin beide Varianten unterstützt.
FPC Compiler Entwickler

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

Re: C/C++ enum in Pascal

Beitrag von Mathias »

Ich bin grade wieder über etwas gestossen.

Für diese Funktion werden Enums gebraucht. Daher musste ich diesen unübersichtlichen Cast machen.

Code: Alles auswählen

gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
    TGstMessageType(int64(GST_MESSAGE_ERROR) or int64(GST_MESSAGE_EOS)));    
Quelle:

Code: Alles auswählen

  TGstMessageType = (
    GST_MESSAGE_UNKNOWN := 0,
    GST_MESSAGE_EOS := 1 shl 0,
    GST_MESSAGE_ERROR := 1 shl 1,
    GST_MESSAGE_WARNING := 1 shl 2,    ...
Es ist auch C-seitig recht idiotisch gemacht.

Code: Alles auswählen

typedef enum
{
  GST_MESSAGE_UNKNOWN           = 0,
  GST_MESSAGE_EOS               = (1 << 0),
  GST_MESSAGE_ERROR             = (1 << 1),
  GST_MESSAGE_WARNING           = (1 << 2),
Daher meine Empfehlung, wen man C-Libs übersetzt, das man besser const anstelle von Enums nimmt.
Dann kann man es ganz ohne Cast sauber lösen:

Code: Alles auswählen

  msg := gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
    GST_MESSAGE_ERROR or GST_MESSAGE_EOS);
Bei h2pas einfach -e mitgeben, dann werden Const erstellt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten