[racket] [FFI] _union and define-cstruct

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Fri Oct 26 17:06:20 EDT 2012

I agree with this. The code Laurent is talking about is my x11 ffi bindings. Laurent, feel free to make this change and push to the repo. I'm not sure why I didn't use the super struct thing to begin with, maybe it didn't exist when I initially wrote the bindings.

https://github.com/kazzmir/x11-racket for anyone interested.

On 10/26/2012 02:26 PM, Matthew Flatt wrote:
> That seems like an ok solution.
>
> I would be tempted to write
>
>  (define-cstruct _XEvent ([type _int]))
>
>  (define-cstruct (_XAnyEvent _XEvent) ([serial _ulong]
>                                        ....))
>  (define-cstruct (_XKeyEvent _XEvent) ([serial _ulong]
>                                        ....))
>  ....
>
> Those declarations more directly fit the sub-structuring that is
> implemented by the union in "Xlib.h", but it doesn't give you
> `XAnyEvent-type', `XKeyEvent-type', etc., and the size of `_XEvent'
> isn't the maximum of the variant sizes.
>
> At Fri, 26 Oct 2012 19:00:01 +0200, Laurent wrote:
>> Oooohh, I think I understand now: the way it was is already sufficiently
>> general.
>> The writer of the initial code took a different direction.
>> Instead of defining a union type, he changes the tag of the pointer
>> depending on what kind of type he needs in the union:
>> (cpointer-push-tag! e XAnyEvent-tag)
>> (case (XAnyEvent-type e)
>>     ((KeyPress) (cpointer-push-tag! e XKeyPressedEvent-tag))
>>     ((KeyRelease) (cpointer-push-tag! e XKeyReleasedEvent-tag))
>>     ....
>>
>> It's pretty smart. Is it the right way to go in general, and should _unions
>> be avoided?
>>
>> Laurent
>>
>> On Fri, Oct 26, 2012 at 6:39 PM, Laurent <laurent.orseau at gmail.com> wrote:
>>
>>> Hi,
>>>
>>> I am trying to convert an FFI cstruct definition into a union.
>>> More exactly, the previous definition was :
>>> (define-cstruct _XEvent
>>>     ((type EventType)))
>>>
>>> with EventType being defined elsewhere.
>>> But this was an incomplete definition, and I now want to translate the
>>> following C union:
>>> typedef union _XEvent {
>>>         int type;        /* must not be changed; first element */
>>>     XAnyEvent xany;
>>>     XKeyEvent xkey;
>>>     // ... the rest for later
>>> } XEvent;
>>>
>>> I searched the collects directory, but I see only a single and too simple
>>> _union use, so I'm not sure how to use it.
>>> I guessed the following:
>>>   (define _XEvent
>>>     (_union EventType ; type
>>>             _XAnyEvent ; xany
>>>             _XKeyEvent ; xkey
>>>             ; etc.
>>>             ))
>>>   (define (XEvent-type ev) (union-ref ev 0))
>>>   (define (XEvent-xany ev) (union-ref ev 1))
>>>   (define (XEvent-xkey ev) (union-ref ev 2))
>>>
>>> However, now I don't use define-cstruct anymore (it would not work with
>>> _union, would it?), so I don't have all the -tag, -pointer, etc. bindings,
>>> which I need.
>>>
>>> What should I do ?
>>>
>>> Thanks,
>>> Laurent
>>>
>>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.