union#

Declare a union class: a C union, reached by pointer and in memory.

Synopsis#

Peta::FFI::record("Keysym", scancode => "i32", sym => "i32", mod => "u16", unused => "u32");
Peta::FFI::record("KeyEvent", type => "u32", timestamp => "u32", windowID => "u32",
                  state => "u8", repeat => "u8", pad => "u8[2]", keysym => "{Keysym}");
Peta::FFI::union("Event", type => "u32", key => "{KeyEvent}", padding => "u8[56]");

my $ev = Event->new;                       # SDL_Event
while (Peta::FFI::call($sdl, "SDL_PollEvent", "(*{Event})i", $ev)) {
    print $ev->key->keysym->sym, "\n" if $ev->type == 0x300;   # SDL_KEYDOWN
}

As record, with every member at offset 0: the union is as large as its largest member, rounded to its strictest alignment. A member that is a record - in a union or a struct - reads as a copy, an object of its class, and is set from one.

A union passes by pointer, *{Class}, and is read and written whole by fetch, store and as a member of a record. Passing it by value

  • as {Class}, or inside a struct passed by value - croaks: libffi has no union type, and a struct of the same size passes differently on some ABIs, which would be a wrong call rather than an error.