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