I’m writing a Zig library that additionally exposes a C-ABI library. Part of the public API is a tagged union. How would I include this union in the C-compatible API?
Obviously I can’t just export the type, so my thought was to have the external functions take in just the tag and an arbitrary payload that I would simply bit-cast to the union payload type. However, I can’t find a way to initialize a union from a tag value that isn’t comptime-known. If it’s comptime-known, I could use @unionInit(Union, @tagName(tag), ...) but of course it can’t be comptime-known. I also can’t just bit-cast the tag (and the payload), because tagged unions can’t participate in bit-casts as they can’t be marked packed or extern.
I’m a bit stuck now and would love some help. Feel free to tell me if you think my approach is entirely wrong, I’m open for feedback!
Stripped-down sample code:
pub const Symbol = union(enum(u32)) { // tag type is C-ABI-compatible, but union isn't
a: u32,
b: i8,
d: void,
}
export fn send_symbol(symbol: Symbol) c_int {
// Symbol can't be used in export fn
}
export fn send_symbol(tag: @typeInfo(Symbol).@"union".tag_type.?, payload: u32) c_int {
// what now?
}