Hi

I found the problem: TGtkBox record layout and size is not correct for Win32 GTK 2 libraries. This causes that "PGtkCombo(c)^.entry" does not work as it should, because address of "entry" field in "TGtkCombo" is different than it should be. TGtkBox is currently defined as

   TGtkBox = record
        container : TGtkContainer;
        children : PGList;
        spacing: gint16;
        flag0: word;
     end;

and with "packing C" FPC understands that spacing and flag0 are packed
together into one 32 bit value. And this is correct for GTK 2 Linux
libraries, but surprisingly inside GTK 2 Win32 dlls GtkBox record (even
though declared the same way in C headers) has different layout, namely
both spacing and flag0 are expanded into 32-bit values. This means that
correct definition of TGtkBox should be

   TGtkBox = record
        container : TGtkContainer;
        children : PGList;
        spacing: {$ifdef WIN32} LongInt {$else} gint16 {$endif};
        flag0: {$ifdef WIN32} LongInt {$else} word {$endif};
     end;

No, this is *not* a bug somewhere in general FPC record aligning
algorithm. You can treat it as a bug in FPC GTK 2 bindings, or you can
treat it as a bug in Win32 GTK 2 libraries (because they apparently are
compiled in such way that struct alignment is different than in Linux).

I'm attaching test program test_align_differ.pas, compile and run this under Win32 and Linux and watch what it prints on stdout under each OS. Results prove that

1. sizes of all three records (TGtkContainer, TGtkBoxModified, TGtkBox)
are the same under Win32 and Linux. So it's not a bug inside FPC compiler with aligning records, because both under Win32 and Linux records are aligned the same in FPC units.


2. At the same time, you can see that definition of TGtkBoxModified does
not work as it should under Linux and definition of TGtkBox does not
work as it should under Win32.

This proves that structures are aligned differently in Linux and Win32
libraries.

Michalis
{$mode delphi}

uses
  glib2, gdk2, gtk2;

{ modified types (they are correct with Win32 GTK 2 libraries,
  but not with Linux GTK 2 libraries)
  ------------------------------------------------------------ }

type
   TGtkBoxModified = record
        container : TGtkContainer;
        children : PGList;
        spacing: LongInt; { changed from 16-bit to 32-bit }
        flag0: LongInt; { changed from 16-bit to 32-bit }
     end;

   TGtkHBoxModified = record
        box : TGtkBoxModified;
     end;

   TGtkComboModified = record
        hbox : TGtkHBoxModified;
        entry : PGtkWidget;
        button : PGtkWidget;
        popup : PGtkWidget;
        popwin : PGtkWidget;
        list : PGtkWidget;
        entry_change_id : guint;
        list_change_id : guint;
        flag0 : word;
        current_button : guint16;
        activate_id : guint;
     end;
   PGtkComboModified = ^TGtkComboModified;

{ end of modified types ---------------------------------------- }

var
  d: pGTKWidget;
  h: pGTKWidget;
  b: pGTKWidget;
  c: pGTKWidget;
  g: pGList;
begin
  gtk_init(@argc, @argv);

  d := gtk_dialog_new;
  gtk_window_set_title(pGTKWindow(d), 'A sample dialog');

  h := pGTKDialog(d)^.vbox;

  c := gtk_combo_new();
  gtk_box_pack_start(pGTKBox(h), c, false, false, 0);
  
  gtk_widget_show(c);
  gtk_widget_show(d);

  Writeln(
    'TGtkContainer ', SizeOf(TGtkContainer), LineEnding,
    'TGtkBoxModified ', SizeOf(TGtkBoxModified), LineEnding,
    'TGtkBox ', SizeOf(TGtkBox));
  writeln('Old values of hom and spacing:');
  Writeln(' unmodified structs ',
    pGTKCombo        (c)^.hbox.box.spacing, ' ',
    pGTKCombo        (c)^.hbox.box.flag0);
  Writeln('   modified structs ',
    pGTKComboModified(c)^.hbox.box.spacing, ' ',
    pGTKComboModified(c)^.hbox.box.flag0);
  gtk_box_set_homogeneous(PGtkBox(c), true);
  gtk_box_set_spacing(PGtkBox(c), 44);
  writeln('New values of hom and spacing:');
  Writeln(' unmodified structs ',
    pGTKCombo        (c)^.hbox.box.spacing, ' ',
    pGTKCombo        (c)^.hbox.box.flag0);
  Writeln('   modified structs ',
    pGTKComboModified(c)^.hbox.box.spacing, ' ',
    pGTKComboModified(c)^.hbox.box.flag0);
    
  gtk_main();
end.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to