[gambit-list] c interface: enums issue

Mikael mikael.rcv at gmail.com
Sun Feb 5 13:54:11 EST 2012


Hi,

2012/2/5 Álvaro Castro-Castilla <alvaro.castro.castilla at 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 at 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 at 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 at 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 at 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 at iro.umontreal.ca
>>>>> https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20120205/53c7f244/attachment.htm>


More information about the Gambit-list mailing list