C/C++ DoppelPointer --> FPC

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

C/C++ DoppelPointer --> FPC

Beitrag von Mathias »

Code: Alles auswählen

SDL_Rect **modes;
modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);

if(modes == (SDL_Rect **)0){  // Wie geht dies in FPC ?
  printf("No modes available!\n");
  exit(-1);
}
SDL_Rect ist so in C/C++ deklariert:

Code: Alles auswählen

typedef struct SDL_Rect {
	Sint16 x, y;
	Uint16 w, h;
} SDL_Rect;
Diese C/C++ Funktion ermittelt, wieviele VideoModus möglich sind.
Die if-Anweisung wird wohl testen, ähnlich eine Nullterminierten Stringes, ob keine Elemente vorhanden sind.
Ich habe folgendes mit Pascal probiert, aber dies gibt ein syntax-Fehler:

Code: Alles auswählen

var
  modus: PPSDL_Rect;
 begin
  modus:=  SDL_ListModes(nil, SDL_FULLSCREEN or SDL_HWSURFACE);
  if modus=TSDL_Rect^^(0) then WriteLn('NULL');
So sieht das PPSDL_Rect in Pascal aus:

Code: Alles auswählen

  PPSDL_Rect = ^PSDL_Rect;
  PSDL_Rect = ^TSDL_Rect;
  TSDL_Rect = record
    x, y: SInt16;
    w, h: UInt16;
  end;
Ich denke, dies ist sehr einfach, wen man weis wie.
Einer eine Idee ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: C/C++ DoppelPointer --> FPC

Beitrag von theo »

Bin nicht ganz sicher, aber ich glaube so etwas ist ein Pointer auf ein Array.

Könnte in etwa wie das sein:

Code: Alles auswählen

type
  ta=Array[0..2] of Pchar;
var
  a:ta;
  b:PPChar;
begin
  a[0]:='1text';
  a[1]:='2text';
  a[2]:='3text';
  b:=@a;
  inc(b);
  ShowMessage(b^);
end;   
So habe ich das dumpf im Hinterkopf. Aber das kann auch Käse sein. :wink:

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

Re: C/C++ DoppelPointer --> FPC

Beitrag von Mathias »

Ja, es ist ein Array mit Pointern, so wie PPChar es ist.

Ich habe dein Beispiel probiert, zuerst dachte ich, es knallt.
Aber aber anscheined geht so etwas:

Code: Alles auswählen

var
  pc: PChar;
begin
  pc := '123456';
  WriteLn(pc);
end.
Dies wird wohl Eigenintelligenz von Pascal sein, das dort Speicher für pc reserviert wird ?


Unterdessen bin ich weiter gekommen, dies schein zu funktionieren:

Code: Alles auswählen

  var
    modus, p: PPSDL_Rect;
    i: integer;
  begin
    modus := SDL_ListModes(nil, SDL_FULLSCREEN or SDL_HWSURFACE);
    if modus = Pointer(0) then begin
      WriteLn('Kein Modus vorhanden');
    end;
    if modus = Pointer(-1) then begin
      WriteLn('Alle Moden vorhanden');
    end;
    p := modus;
    i := 0;
    while p[i] <> nil do begin
      WriteLn('Widht:', p[i]^.w: 5, ' Height:', p[i]^.h: 5);
      Inc(i);
    end;
Ob dies korrekt ist, keine Ahnung.


Dies ist noch die C/C++ Source dazu: https://www.libsdl.org/release/SDL-1.2. ... modes.html
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++ DoppelPointer --> FPC

Beitrag von Winni »

Mathias hat geschrieben:
Do 5. Jan 2023, 17:34
Dies wird wohl Eigenintelligenz von Pascal sein, das dort Speicher für pc reserviert wird ?
Hi!

Jo - da ist in den Anfängen von Delphi viel gebastelt worden, weil

* Einerseits hatte man die Pascal-Strings in string[255] und Ansi
* Andererseits hatte man von Windows die nullterminierten C-Strings.

Wenn man nun mit der Windows-API rummacht, stellt sich die Konvertierung.

Damit nicht ewig Speicher reserviert und konvertiert werden musste, hat PChar eine ganze Menge Kompatibiltäts-Mechanismen mitbekommen, z.B.

String := String+Pchar;

Writeln (pchar);

Pchar := Pchar(String);

Winni

PascalDragon
Beiträge: 825
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++ DoppelPointer --> FPC

Beitrag von PascalDragon »

Mathias hat geschrieben:
Do 5. Jan 2023, 16:35
Einer eine Idee ?
Das hier

Code: Alles auswählen

if(modes == (SDL_Rect **)0){  // Wie geht dies in FPC ?
Ist einfach nur eine Prüfung, ob der zurückgegebene Pointer gültig ist. Also in FPC entweder

Code: Alles auswählen

if modes = Nil then begin
oder

Code: Alles auswählen

if not Assigned(modes) then begin
FPC Compiler Entwickler

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

Re: C/C++ DoppelPointer --> FPC

Beitrag von Mathias »

Genau, das 0 muss nil sein, aber das "-1".

Code: Alles auswählen

if(modes == (SDL_Rect **)0){
  printf("No modes available!\n");
  exit(-1);
}
/* Check if our resolution is restricted */
if(modes == (SDL_Rect **)-1){
  printf("All resolutions available.\n");
}
Was ich da vermute, normalerweise ist "modes" ein Zeiger auf eine Adresse. Und in diesem Beispiel wurde die Adresse "-1" missbraucht. Dies macht eigentlich auch Sinn. Im Falle eine 32Bit-Rechners, wäre die das letzte Byte eines mit 4GB bestückten Rechners. Somit könnte die Daten in "modes" maximal 1Byte gross sein, was unmöglich ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 825
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++ DoppelPointer --> FPC

Beitrag von PascalDragon »

Mathias hat geschrieben:
Fr 6. Jan 2023, 17:14
Was ich da vermute, normalerweise ist "modes" ein Zeiger auf eine Adresse. Und in diesem Beispiel wurde die Adresse "-1" missbraucht. Dies macht eigentlich auch Sinn. Im Falle eine 32Bit-Rechners, wäre die das letzte Byte eines mit 4GB bestückten Rechners. Somit könnte die Daten in "modes" maximal 1Byte gross sein, was unmöglich ist.
Der Rückgabewert von SDL_ListModes ist entweder Nil für keine verfügbaren Modi, ein Zeiger auf eine Liste von SDL_Rect Zeigern oder PPSDL_Rect(-1) (was unter 32-bit $ffffffff und unter 64-bit $ffffffffffffffff ist), falls alle Modi verfügbar sind. Demnach kannst du einfach auf PPSDL_Rect(-1) als zweite Bedingung prüfen.
FPC Compiler Entwickler

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

Re: C/C++ DoppelPointer --> FPC

Beitrag von Mathias »

PPSDL_Rect(-1)
Ich dachte es doch, das es etwas sehr simples ist.

Danke.

Code: Alles auswählen

  PPSDL_Rect = ^PSDL_Rect;
  PSDL_Rect = ^TSDL_Rect;
  TSDL_Rect = record
    x, y: SInt16;
    w, h: UInt16;
  end;
Im Nachhinein recht logisch, das "PP" ist nichts anderes als **.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: C/C++ DoppelPointer --> FPC

Beitrag von Mathias »

In folgendem Beispiel spuckt WriteLn 2 mal das Gleiche aus. Egal, ob ich es mit oder ohne @ mitgebe.
Damit nicht ewig Speicher reserviert und konvertiert werden musste, hat PChar eine ganze Menge Kompatibiltäts-Mechanismen mitbekommen, z.B.

Code: Alles auswählen

var
  pc1, pc2: array[0..255] of Char;
begin
  ...
  SDL_VideoDriverName(@pc1, 512);
  WriteLn(pc1);
  SDL_VideoDriverName(pc2, 512);
  WriteLn(pc2);  
Die Deklaration von SDL:

Code: Alles auswählen

function SDL_VideoDriverName(namebuf: PChar; maxlen: Integer): PChar;......
Ist das auch so eine Eigenintelligenz von PChar ?
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++ DoppelPointer --> FPC

Beitrag von Winni »

Hi!

Hatte ich doch geschrieben, dass writeln auch angepasst wurde.

Ach so - Du fragst nach dem @.

Pchar ist eine Pointer auf einen Char.
Ein array[0..255] of Char ist implizit ein pchar.

Pchar ist für sein kompatibles Verhalten mit Strings dahingehend "dressiert" worden, dass das @ nicht mehr notwendig ist.

Geht doch aus obigen Beispiel hervor:

StringA := StringB + MyPcharC;

Winni

Antworten