array of const

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1435
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of const

Beitrag von fliegermichl »

Danke für die Erklärung.

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

Re: array of const

Beitrag von Mathias »

Ist eine Mischung aus "array of const" und "varargs" möglich ?

Ich habe folgendes in den GTK"-Sourcen entdeckt:

Code: Alles auswählen

function gtk_tree_store_new(n_columns:gint):PGtkTreeStore; cdecl; overload; external gtklib;
function gtk_tree_store_new(n_columns:gint; args:array of const):PGtkTreeStore; cdecl; overload; varargs; external gtklib;
In den C-Sourcen sieht dies so aus:

Code: Alles auswählen

GtkTreeStore *gtk_tree_store_new              (gint          n_columns,   ...);
Eigentlich nichts besonderes.

Ich bin in folgendem Beispiel stecken geblieben: https://zetcode.com/gui/gtk2/gtktreeview/ 3. Beispiel (treeview.c)

Code: Alles auswählen

const
  COLUMN = 0;
  NUM_COLS = 1;
 ....
var
  treestore: PGtkTreeStore;
begin  
    treestore := gtk_tree_store_new(NUM_COLS, [G_TYPE_STRING]);
    
    gtk_tree_store_append(treestore, @toplevel, nil);
    gtk_tree_store_set(treestore, @toplevel, COLUMN, 'Interpreter Sprachen', -1);

    gtk_tree_store_append(treestore, @child, @toplevel);
    gtk_tree_store_set(treestore, @child, COLUMN, 'Python', -1);
    .....
Nur wird mir mit SIGSEGV quitiert. :roll:

Kann mir einer weiter helfen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: array of const

Beitrag von Socke »

Mathias hat geschrieben:
Mi 22. Mär 2023, 09:09
Ist eine Mischung aus "array of const" und "varargs" möglich ?
array of const wird bei external cdecl doch automatisch zu varargs? Ich hätte den varargs-Modifier also bei der ersten Zeile erwartet (siehe auch https://www.freepascal.org/docs-html/ref/refsu97.html)

Also so herum:

Code: Alles auswählen

function gtk_tree_store_new(n_columns:gint):PGtkTreeStore; cdecl; overload; varargs; external gtklib;
function gtk_tree_store_new(n_columns:gint; args:array of const):PGtkTreeStore; cdecl; overload; external gtklib;
Edit: Die GTK4-Dokumentation schlägt vor, dass du dich mit TreeListModel beschäftigen solltest.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: array of const

Beitrag von Mathias »

Also so herum:
Also habe ich es richtig verstanden, ein Bug in der gtk2-Unit ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: array of const

Beitrag von Mathias »

Code: Alles auswählen

    gtk_tree_store_set(treestore, @child, COLUMN, 'CC', -1);  // geht
     gtk_tree_store_set(treestore, @child, COLUMN, 'C', -1);  // SIGSEV
Anscheinend gibt es noch ein Problem bei der Typenumwandlung. Ein einzelner Buchstabe wird anscheinend als Char implementiert.

Mit einer manuellen Umwandlung geht es.

Code: Alles auswählen

    gtk_tree_store_set(treestore, @child, COLUMN, PChar('C'), -1);
Da hat C/C++ ausnahmsweise Pascal eine Nasenlänge voraus. Dort muss man so "C" oder 'C' deklarieren.
Gut ich gebe zu, ich arbeite hier mit einer Brücke von Pascal nach C-libs.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: array of const

Beitrag von Socke »

Mathias hat geschrieben:
Mi 22. Mär 2023, 13:58
Da hat C/C++ ausnahmsweise Pascal eine Nasenlänge voraus. Dort muss man so "C" oder 'C' deklarieren.
Gut ich gebe zu, ich arbeite hier mit einer Brücke von Pascal nach C-libs.
In C/C++ gibt es halt keinen Unterschied zwischen einem und mehreren Zeichen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: array of const

Beitrag von Mathias »

Ich stehe wieder mal vor einem Problem. Wieso kann ich eine "array of const" innerhalb von FPC weiterleiten, aber auf eine clib geht es nicht ?

Code: Alles auswählen

  procedure vaTest(args: array of const); cdecl; external 'c';

  procedure test2(ca: array of const);
  begin
  end;

  procedure test(ca: array of const);
  begin
    test2(ca);           // geht
    vaTest([12, 'abc']); // geht
    vaTest(ca);          // geht nicht
  end;

begin
  test([123, 456]);
end.  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

martin_frb
Beiträge: 573
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: array of const

Beitrag von martin_frb »

Mathias hat geschrieben:
Mi 16. Nov 2022, 17:24

Code: Alles auswählen

function XGetIMValues(para1:PXIM; dotdotdot:array of const):Pchar;cdecl;external libX11;
Da wird eine "array of const" verlangt.
Da wollte ich folgendes deklarieren;

Code: Alles auswählen

  var
    ac:array of const;
Da motzt der Colpiler "Illegal expression"

Wie kann ich dieses Problem lösen ?

Code: Alles auswählen

program Project1; {$mode objfpc}
uses SysUtils;

var
  b: Array of TVarRec;
procedure Foo(a: array of const);
var
  i: Integer;
begin
  SetLength(b, Length(a));
  for i := 0 to Length(a) - 1 do
    b[i] := a[i];
end;

begin
  foo([1,'ab', 1.3]);
  writeln(Format('%d %s %f', b));
  readln;
end.

Aber Vorsicht!

Strings sind nicht ref-counted.
Wenn der string der an foo übergeben wurde sich ändert, dann wird der Wert in b[1] zum dangling pointer.

Antworten