I tried to import a Gtk enumeration constant:
;; Local Variables: ;; compile-command: "gsc -cc-options "`pkg-config --cflags gtk+-2.0`" -ld-options "`pkg-config --libs gtk+-2.0`" -exe enum.scm" ;; End:
(c-declare "#include <gtk/gtk.h>")
(c-define-type GtkWindowType "GtkWindowType")
(define gtk-window-toplevel ((c-lambda () GtkWindowType "___result = GTK_WINDOW_TOPLEVEL;")))
(write gtk-window-toplevel)
But I get a segmentation fault when I run the program.
When I use int instead of the enum type the code does not segfault:
(define gtk-window-toplevel ((c-lambda () int "___result = GTK_WINDOW_TOPLEVEL;")))
Does this mean, that I have to ignore all C enum types and treat them as ints?
The documentation for c-define-type does not say much about enumerations:
http://www.iro.umontreal.ca/~gambit/doc/gambit-c.html#c_002ddefine_002dtype
Afficher les réponses par date
On 2011-11-02, at 12:05 PM, Vok Vojwo wrote:
I tried to import a Gtk enumeration constant:
;; Local Variables: ;; compile-command: "gsc -cc-options "`pkg-config --cflags gtk+-2.0`" -ld-options "`pkg-config --libs gtk+-2.0`" -exe enum.scm" ;; End:
(c-declare "#include <gtk/gtk.h>")
(c-define-type GtkWindowType "GtkWindowType")
(define gtk-window-toplevel ((c-lambda () GtkWindowType "___result = GTK_WINDOW_TOPLEVEL;")))
(write gtk-window-toplevel)
But I get a segmentation fault when I run the program.
When I use int instead of the enum type the code does not segfault:
(define gtk-window-toplevel ((c-lambda () int "___result = GTK_WINDOW_TOPLEVEL;")))
Does this mean, that I have to ignore all C enum types and treat them as ints?
In C, an enum is an int. In the FFI code, you have to be precise about the concrete type so that the C interface can do the appropriate conversions between C and Scheme. When you say
(c-define-type GtkWindowType "GtkWindowType")
the Gambit compiler has an abstract knowledge of that type, and no knowledge of its representation. So you have to say instead:
(c-define-type GtkWindowType int)
and then you can use it like this:
(define gtk-window-toplevel ((c-lambda () GtkWindowType "___result = GTK_WINDOW_TOPLEVEL;")))
Alternatively, use this macro to import C enums and constants:
(define-macro (import-int-constants . names) `(begin ,@(map (lambda (name) `(define ,name ((c-lambda () int ,(string-append "___result = " (symbol->string name) ";"))))) names)))
(import-int-constants GTK_WINDOW_TOPLEVEL )
The documentation for c-define-type does not say much about enumerations:
http://www.iro.umontreal.ca/~gambit/doc/gambit-c.html#c_002ddefine_002dtype
I'll add something to the doc to explain this.
Marc
2011/11/2 Marc Feeley feeley@iro.umontreal.ca:
Alternatively, use this macro to import C enums and constants:
I am experimenting with a symbol version:
(define gtk-window-new (let ((toplevel ((c-lambda () int "___result = GTK_WINDOW_TOPLEVEL;"))) (popup ((c-lambda () int "___result = GTK_WINDOW_POPUP;"))) (new (c-lambda (int) GtkWidget* "gtk_window_new"))) (lambda (type) (new (case type ((toplevel) toplevel) ((popup) popup) (else "gtk-window-new: invalid type: " type))))))
This seems to be more natural in Scheme and the top level environment would be smaller. But the code would be slower because of the case dispatching. And every mapped C function accepting enumerations would have three closures: the let, the lambda and the c-lambda.
Is this inappropriate expensive?
It's fine as long as the case listing has few elements (<30-50 somewhere). Your else clause probably wants an error call in it btw.
2011/11/2 Vok Vojwo ceving@gmail.com
2011/11/2 Marc Feeley feeley@iro.umontreal.ca:
Alternatively, use this macro to import C enums and constants:
I am experimenting with a symbol version:
(define gtk-window-new (let ((toplevel ((c-lambda () int "___result = GTK_WINDOW_TOPLEVEL;"))) (popup ((c-lambda () int "___result = GTK_WINDOW_POPUP;"))) (new (c-lambda (int) GtkWidget* "gtk_window_new"))) (lambda (type) (new (case type ((toplevel) toplevel) ((popup) popup) (else "gtk-window-new: invalid type: " type))))))
This seems to be more natural in Scheme and the top level environment would be smaller. But the code would be slower because of the case dispatching. And every mapped C function accepting enumerations would have three closures: the let, the lambda and the c-lambda.
Is this inappropriate expensive? _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On Wed, 2011-11-02 at 21:25 +0200, Mikael wrote:
It's fine as long as the case listing has few elements (<30-50 somewhere).
This may be correct, but Marc implemented an algorithm for compiling large case statements into very fast code.
I tried to find a reference to this work somewhere but failed; Marc, did I imagine it?
Brad