[racket] [FFI] _union and define-cstruct
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