SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Beitrag von Mathias »

Die Funktion für das starten eines Thread mit SDL sieht so aus:

Code: Alles auswählen

function SDL_CreateThread(fn: PInt; data: Pointer): PSDL_Thread;
cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_CreateThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
{$EXTERNALSYM SDL_CreateThread}
Der erste Parameter ist ein Zeiger auf die Funktion, welche der Thread ausführen soll. Nur ist es dort mit "PInt" deklariert, und ein PInt ist ein gewähnlicher Integer, welcher 32bit ist. "PInt = ^Integer;".
Ich habe die Funktion modifiziert und den Pint durch Pointer ausgetauscht und ein Pointer hat 64bit.

Code: Alles auswählen

function SDL_CreateThread(fn: pointer; Data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
Jetzt funktioniert es.
Ist dies ein Bug, oder wurde dies bewusst gemacht ?

Für den Test, habe ich habe ich die veraltet Unit "dsl" verwendet, welche standardmässig bei Lazarus dabei ist. Und als OS verwende ich ein 64bit Linux.
Zuletzt geändert von Mathias am So 15. Jan 2023, 09:13, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von Mathias »

Ich habe es noch mit C/C++ probiert, da bin ich auf folgendes in "SDL_thread.h" gestossen:

Code: Alles auswählen

extern DECLSPEC SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data);
Die verwenden auch nur ein gewöhnlicher Interger und der ist in C/C++ auch nur 32bit.
Das Programm wird wohl kompiliert, aber es schmiert dann ab, mit folgendem Fehler ab.
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
XIO: fatal IO error 0 (Success) on X server ":0"
sdl_test: ../../src/xcb_io.c:278: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
after 116 requests (116 known processed) with 0 events remaining.
Abgebrochen (Speicherabzug geschrieben)
Somit vermute ich, das schon ein Bug in den C-Sourcen ist.

Dies ist noch das Tutorial dazu: https://lazyfoo.net/SDL_tutorials/lesson33/index.php


Nachtrag: Auf dem 32bit Raspi läuft es kurz, aber dann schmiert es auch ab.
Ein 1-2 mal läuft die Schleife durch.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
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: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 11. Jan 2023, 17:45
Ich habe es noch mit C/C++ probiert, da bin ich auf folgendes in "SDL_thread.h" gestossen:

Code: Alles auswählen

extern DECLSPEC SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data);
Die verwenden auch nur ein gewöhnlicher Interger und der ist in C/C++ auch nur 32bit.
Bitte, wenn du dich mit C-Headern beschäftigst, dann lerne doch auch bitte wie Parameter in C deklariert werden: Das int (SDLCALL *fn)(void *) ist ein Funktionszeiger auf eine Funktion, die einen void*-Parameter nimmt und ein int zurückgibt und dabei die SDLCALL Aufrufkonvention verwendet.

Das Gegenstück für FPC wäre also function Tfn(aArg: Pointer): LongInt; SDLCALL; (unter der Annahme, dass ein SDLCALL-Makro für die passende Aufrufkonvention deklariert ist).

Das heißt also, dass die Übersetzung in Pascal falsch ist.
FPC Compiler Entwickler

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

Re: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von Mathias »

Das heißt also, dass die Übersetzung in Pascal falsch ist.
Ich habe einen Issue ausgelöst, da ich denke, das dies schnell behoben ist.

https://gitlab.com/freepascal.org/fpc/s ... sues/40112
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von Mathias »

Das Problem wurde schon behoben.
In der aktuellen Trunk läuft es schon.
Ein Hoch an das Team.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von Mathias »

Ich habe nochmals ein Bug gefunden, bei SDL_WaitThread.
In C/C++ sieht es so aus:

Code: Alles auswählen

extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread *thread, int *status);
In der "sdl.pas" so:

Code: Alles auswählen

procedure SDL_WaitThread(thread: PSDL_Thread; var status: Integer);
cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WaitThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
{$EXTERNALSYM SDL_WaitThread}
Da habe ich folgendes probiert, was aber kompiliert wird, aber das Programm bricht mit "Unknow exception code 6" ab.
Und auf der Konsole kommt noch "free(): invalid pointer",

Code: Alles auswählen

procedure SDL_WaitThread(thread: PSDL_Thread; status: PInteger);
cdecl; external {$IFNDEF NDS}{$IFDEF __GPC__}name 'SDL_WaitThread'{$ELSE} SDLLibName{$ENDIF __GPC__}{$ENDIF};
{$EXTERNALSYM SDL_WaitThread}
Nach meines Wissens, ist ein "int *i" ein PInteger in Pascal.

Code: Alles auswählen

var
  thread: PSDL_Thread;
 ... 
  SDL_WaitThread(@thread, nil);
Im C/C++ Tutorial sieht es so aus:

Code: Alles auswählen

 SDL_WaitThread( consumerThread, NULL );
Fast zu unterst.
https://lazyfoo.net/SDL_tutorials/lesson34/index.php

Einer einer Idee was da faul ist ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SDL 1.2 - SDL_CreateThread und 64Bit OS

Beitrag von theo »

Mathias hat geschrieben:
So 15. Jan 2023, 09:02

Code: Alles auswählen

var
  thread: PSDL_Thread;
 ... 
  SDL_WaitThread(@thread, nil);
Ich kenne die Deklarationen nicht, aber wenn PSDL_Thread schon ein Pointer ist, dann kannst/musst du den ohne @ übergeben.

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

Re: SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Beitrag von Mathias »

Ich kenne die Deklarationen nicht, aber wenn PSDL_Thread schon ein Pointer ist, dann kannst/musst du den ohne @ übergeben.
Danke, dies war das Übel.
Aber irgendwie ist "status" doch nicht echte C-Norm. Bei den meisten libs, welche in C geschrieben sind, muss man die Variablen mir einem @ übergeben, wen man einen Rückgabewert will. C, kennt keine "var" im Funktions-Kopf.
Wie bei C:

Code: Alles auswählen

procedure SDL_WaitThread(thread: PSDL_Thread; status: pcint) cdecl;
Pascal mit var:

Code: Alles auswählen

procedure SDL_WaitThread(thread: PSDL_Thread; var status: Integer)
Das Original von der Linux man. https://linux.die.net/man/3/sdl_waitthread

So wie es scheint funktioniert beides, und je nach dem, wer die Header übersetzt, wird die eine oder andere Variante verwendet.
Sehe ich dies richtig so ?


Ich habe gerade in den neusten SDL2 Übersetzungen nachgeguckt, dort wird es mit pcint gemacht.

Code: Alles auswählen

procedure SDL_WaitThread(thread: PSDL_Thread; status: pcint) cdecl; external SDL_LibName {$IFDEF DELPHI} {$IFDEF MACOS} name '_SDL_WaitThread' {$ENDIF}{$ENDIF};
https://github.com/PascalGameDevelopmen ... thread.inc

Nachtrag: Die Pointer-Variante ist besser als die mit "var".
Weil es bei dieser Funktion die Möglichkeit gibt, auch "nil" mitzugeben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
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: SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Beitrag von PascalDragon »

Mathias hat geschrieben:
So 15. Jan 2023, 12:50
Sehe ich dies richtig so ?
Ja, manche Units haben auch beiden Varianten (die Windows Unit zum Beispiel). Und auf ABI Ebene sind beide Varianten equivalent (das gilt auch für out, wenn man eine Funktion hat, die den Parameter nur für Ausgabe nutzt).
Mathias hat geschrieben:
So 15. Jan 2023, 12:50
Nachtrag: Die Pointer-Variante ist besser als die mit "var".
Weil es bei dieser Funktion die Möglichkeit gibt, auch "nil" mitzugeben.
Wer sagt, dass es mit var nicht geht? ;)

Code: Alles auswählen

SDL_WaitThread(thread, Integer(Nil^))
FPC Compiler Entwickler

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

Re: SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Beitrag von Mathias »

Mit deinem nil^ geht es.

Aber da knall es:

Code: Alles auswählen

    WriteLn(LongInt(nil^));
Wie so geht es bei SDL_WaitThread und bei WriteLn nicht ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
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: SDL 1.2 - SDL_CreateThread & SDL_WaitThread mit 64Bit OS

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 18. Jan 2023, 12:40
Aber da knall es:

Code: Alles auswählen

    WriteLn(LongInt(nil^));
Wie so geht es bei SDL_WaitThread und bei WriteLn nicht ?
Writeln ist keine Funktion, sondern ein Compiler Intrinsic. Du kannst dich also nicht darauf berufen, dass Dinge mit ordinären Parametern funktionieren, aber nicht mit Intrinsics oder andersrum.
FPC Compiler Entwickler

Antworten