I’m working on wlhs, a library that will try to use the C ffi to create a Haskell wrapper for the Wlroots library, which aids in the development of Wayland compositors.
We have a templating language to make writing the bindings go a little more smoothly, but I’m also willing to write Storable instances by hand when I need to.
I’ve run into an issue where I need to write Haskell types for this struct, that contains a C union (I did 4 years of C in college and I’d never seen a union in my life until I started this project).
struct wlr_xdg_surface_configure {
struct wlr_xdg_surface *surface;
struct wl_list link; // wlr_xdg_surface.configure_list
uint32_t serial;
union {
struct wlr_xdg_toplevel_configure *toplevel_configure;
struct wlr_xdg_popup_configure *popup_configure;
};
};
My understanding of how a union in C works is: “A union contains a list of field names and their types, and only one of those fields can be defined at a time. The C compiler will ‘reserve’ enough space (in the memory layout of the struct) for the largest element in the union, so that every element in the union can fit within the allotted space.”
So, since in this example, both of the fields are pointers, it makes sense that we could just reserve space for one pointer in the Storable instance.
What I don’t understand is
- how would consumers of our library know from the types which member of the union is ‘active’ and occupying that space in memory
- how do I define a Haskell type that either has one field or another, but not both.
I’m a Haskell newbie, I’ve done some Advent Of Code and I’ve been self-studying for about two years now with no practical project experience. I started contributing to WLHS because I thought the FFI could be a decent place to start contributing, since it doesn’t require knowledge of Type Families, Functional Dependencies, or GADTs and the like.
I’ve tried doing an internet search for “how to define a Haskell C FFI type for a C union” and not found any materials that seem like they can solve the problem.
When writing hsc2hs code, what is the best way to define C unions?
The repository for wlhs is here www.github.com/bradrn/wlhs, and my in-progress pull request is here Wlr scene by MattBrooks95 · Pull Request #18 · bradrn/wlhs · GitHub , where I’ve written some structs that had unions, but ended up needing to comment them out and use an empty data declaration temporarily, so that it builds.
The wlr_xdg_surface struct is the one that I started trying to write, and then stopped because I realized that I didn’t know how to represent the union.