Hi Mikael,
This is the solution that seems to work, wrapping it.
(define cairo-create-surface (c-lambda (unsigned-char* int int int int) cairo-surface-t* " cairo_format_t format; switch (___arg2) { case -1: format = CAIRO_FORMAT_INVALID; break; case 0: format = CAIRO_FORMAT_ARGB32; break; case 1: format = CAIRO_FORMAT_RGB24; break; case 2: format = CAIRO_FORMAT_A8; break; case 3: format = CAIRO_FORMAT_A1; break; case 4: format = CAIRO_FORMAT_RGB16_565; break; default: format = CAIRO_FORMAT_RGB24; break; } ___result = cairo_image_surface_create_for_data(___arg1, format, ___arg3, ___arg4, ___arg5); "))
It is rather inconvenient, though. I think there should be a better way. Also, this crashes Gambit, just per se: (define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")))
Best regards,
Álvaro
2012/2/5 Mikael mikael.rcv@gmail.com
Hi, do something like this: In cairo-image-surface-create-for-data, do printf("Wnt %i got %i\n",CAIRO_FORMAT_RGB24,___arg2); and rerun your previous tests, do they make more sense now? In case the both values printed are the same, your sigsegvcomes from elsewhere. Brgds
2012/2/5 Álvaro Castro-Castilla alvaro.castro.castilla@gmail.com
hi Mikael,
Thanks for your response. Unfortunately, your solution also breaks. Actually, it is doing more or less the same I did. What you say should be used like this, right?: (image-surface (cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) (CAIRO_FORMAT_RGB24) maxx maxy (SDL::screen-pitch sdl-surface)))
In case you have (define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")) already, you should type only CAIRO_FORMAT_RGB24 here not (CAIRO_FORMAT_RGB24).
What I was proposing just decides the output at runtime (the argument is an int, but passed to a function that converts it into a enum -should convert-): (image-surface (cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) (cairo-format CAIRO_FORMAT_RGB24) maxx maxy (SDL::screen-pitch sdl-surface)))
In the Scheme world I think there should only be the need for one representation/form of the C constant.
But the result is the same: segfault. Using your first solution
(returning an int) causes the same problem I got at the beginning: (cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f584104c000> 0 500 500 2000)
To make this one spin, just declare the second argument of this procedure as an int also. Does it work?
Thanks for your help.
Best regards
On Sun, Feb 5, 2012 at 6:35 PM, Mikael mikael.rcv@gmail.com wrote:
If those are int consts from the C header files of the lib, then import them as is fromt here (define CAIRO_FORMAT_ARGB32 ((c-lambda () int "___result = CAIRO_FORMAT_ARGB32;")) etc. , and any arguments that need them declare as int too.
If they're C enums, maybe you want another datatype declaration of them than int - though I suppose int ought to be generally viable for that too.
The exception in your example below is not so strange, as the second arg is an int while the procedure is declared as cairo-format-t. For it to work, I suppose define CAIRO_FORMAT_RGB24 to ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")) . Works?
2012/2/5 Álvaro Castro-Castilla alvaro.castro.castilla@gmail.com
Hi,
I'm using my ffi cairo bindings, that worked fine in the past. However now that I'm using Gambit compiled with C++ support it stopped working.
I got this error:
*** ERROR IN main-sdl#main, "main-sdl.scm"@19.24 -- (Argument 2) Can't convert to C type (cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f33ba191000> 1 500 500 2000)
On the ffi side, things are declared like this:
(c-define-type cairo-format-t "cairo_format_t") (define CAIRO_FORMAT_ARGB32 0) (define CAIRO_FORMAT_RGB24 1) (define CAIRO_FORMAT_A8 2) (define CAIRO_FORMAT_A1 3) (define CAIRO_FORMAT_RGB16_565 4) (define cairo-image-surface-create-for-data (c-lambda (unsigned-char* cairo-format-t int int int) cairo-surface-t* "cairo_image_surface_create_for_data"))
And used like this:
(cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) CAIRO_FORMAT_RGB24 maxx maxy (SDL::screen-pitch sdl-surface))
I've tried with this idea:
(define cairo-format (c-lambda (int) cairo-format-t " switch (___arg1) { case 0: ___result = CAIRO_FORMAT_ARGB32; break; case 1: ___result = CAIRO_FORMAT_RGB24; break; // and so on... } "))
And then calling on the Scheme side "(cairo-format CAIRO_FORMAT_RGB24)" instead of just using the int directly, but it segfaults.
How should I really handle enums properly?
Best regards,
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
Afficher les réponses par date
Hi,
2012/2/5 Álvaro Castro-Castilla alvaro.castro.castilla@gmail.com
Hi Mikael,
This is the solution that seems to work, wrapping it.
(define cairo-create-surface (c-lambda (unsigned-char* int int int int) cairo-surface-t* " cairo_format_t format; switch (___arg2) { case -1: format = CAIRO_FORMAT_INVALID; break; case 0: format = CAIRO_FORMAT_ARGB32; break; case 1: format = CAIRO_FORMAT_RGB24; break; case 2: format = CAIRO_FORMAT_A8; break; case 3: format = CAIRO_FORMAT_A1; break; case 4: format = CAIRO_FORMAT_RGB16_565; break; default: format = CAIRO_FORMAT_RGB24; break; } ___result = cairo_image_surface_create_for_data(___arg1, format, ___arg3, ___arg4, ___arg5); "))
Indeed that works - and in Scheme you just make corresponding defines, i.e. (define cairo-format-rgb24 1) etc. Normally this translation you do is not beneeded as the constants can be used in themselves, which normally works as in the example below:
It is rather inconvenient, though. I think there should be a better way. Also, this crashes Gambit, just per se: (define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")))
Umm.. uhu. What is cairo_format_t:s type declaration in C?
Anyhow you got it working now.
Best regards,
Álvaro
2012/2/5 Mikael mikael.rcv@gmail.com
Hi, do something like this: In cairo-image-surface-create-for-data, do printf("Wnt %i got %i\n",CAIRO_FORMAT_RGB24,___arg2); and rerun your previous tests, do they make more sense now? In case the both values printed are the same, your sigsegvcomes from elsewhere. Brgds
2012/2/5 Álvaro Castro-Castilla alvaro.castro.castilla@gmail.com
hi Mikael,
Thanks for your response. Unfortunately, your solution also breaks. Actually, it is doing more or less the same I did. What you say should be used like this, right?: (image-surface (cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) (CAIRO_FORMAT_RGB24) maxx maxy (SDL::screen-pitch sdl-surface)))
In case you have (define CAIRO_FORMAT_RGB24 ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")) already, you should type only CAIRO_FORMAT_RGB24 here not (CAIRO_FORMAT_RGB24).
What I was proposing just decides the output at runtime (the argument is an int, but passed to a function that converts it into a enum -should convert-): (image-surface (cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) (cairo-format CAIRO_FORMAT_RGB24) maxx maxy (SDL::screen-pitch sdl-surface)))
In the Scheme world I think there should only be the need for one representation/form of the C constant.
But the result is the same: segfault. Using your first solution
(returning an int) causes the same problem I got at the beginning: (cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f584104c000> 0 500 500 2000)
To make this one spin, just declare the second argument of this procedure as an int also. Does it work?
Thanks for your help.
Best regards
On Sun, Feb 5, 2012 at 6:35 PM, Mikael mikael.rcv@gmail.com wrote:
If those are int consts from the C header files of the lib, then import them as is fromt here (define CAIRO_FORMAT_ARGB32 ((c-lambda () int "___result = CAIRO_FORMAT_ARGB32;")) etc. , and any arguments that need them declare as int too.
If they're C enums, maybe you want another datatype declaration of them than int - though I suppose int ought to be generally viable for that too.
The exception in your example below is not so strange, as the second arg is an int while the procedure is declared as cairo-format-t. For it to work, I suppose define CAIRO_FORMAT_RGB24 to ((c-lambda () cairo-format-t "___result = CAIRO_FORMAT_RGB24;")) . Works?
2012/2/5 Álvaro Castro-Castilla alvaro.castro.castilla@gmail.com
Hi,
I'm using my ffi cairo bindings, that worked fine in the past. However now that I'm using Gambit compiled with C++ support it stopped working.
I got this error:
*** ERROR IN main-sdl#main, "main-sdl.scm"@19.24 -- (Argument 2) Can't convert to C type (cairo#cairo-image-surface-create-for-data '#<|unsigned char*| #16 0x7f33ba191000> 1 500 500 2000)
On the ffi side, things are declared like this:
(c-define-type cairo-format-t "cairo_format_t") (define CAIRO_FORMAT_ARGB32 0) (define CAIRO_FORMAT_RGB24 1) (define CAIRO_FORMAT_A8 2) (define CAIRO_FORMAT_A1 3) (define CAIRO_FORMAT_RGB16_565 4) (define cairo-image-surface-create-for-data (c-lambda (unsigned-char* cairo-format-t int int int) cairo-surface-t* "cairo_image_surface_create_for_data"))
And used like this:
(cairo-image-surface-create-for-data (SDL::surface-pixels sdl-surface) CAIRO_FORMAT_RGB24 maxx maxy (SDL::screen-pitch sdl-surface))
I've tried with this idea:
(define cairo-format (c-lambda (int) cairo-format-t " switch (___arg1) { case 0: ___result = CAIRO_FORMAT_ARGB32; break; case 1: ___result = CAIRO_FORMAT_RGB24; break; // and so on... } "))
And then calling on the Scheme side "(cairo-format CAIRO_FORMAT_RGB24)" instead of just using the int directly, but it segfaults.
How should I really handle enums properly?
Best regards,
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list