[racket] [FFI] _union and define-cstruct

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Oct 26 16:26:28 EDT 2012

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

Posted on the users mailing list.