```{index} single: record (Peta::FFI) ``` ```{index} single: Peta::FFI::record ``` # record Declare a record class: a C struct, passed by value or by pointer. ## Synopsis ```perl Peta::FFI::record("My::Point", x => "d", y => "d"); Peta::FFI::record("My::Rect", origin => "{My::Point}", size => "{My::Point}"); my $p = My::Point->new(x => 1.5, y => -2); print $p->x, "\n"; # 1.5 $p->y(4); # set # struct Point point_add(struct Point, struct Point); my $sum = Peta::FFI::call($lib, "point_add", "({My::Point}{My::Point}){My::Point}", $p, $p); # void point_scale(struct Point *, double); Peta::FFI::call($lib, "point_scale", "(*{My::Point}d)v", $p, 2); ``` ## Members Each member is a name and its type, in the order of the C struct: the integer types, `f`, `d`, `b`, `o`, `p` (a `const char *`), a fixed array of numbers or `o` such as `u8[16]`, and another record by value, `{Class}`. The layout - each member's offset and the size and alignment of the whole - is the C compiler's for the platform, as libffi computes it. ## The class `Class->new(member => value, ...)` makes a zeroed record and sets the members given. Each member has an accessor: `$r->name` reads it, `$r->name($value)` sets it; an array member also takes `($index)`, `($index, $value)` and an array reference; a record member reads as a copy, an object of its class, and is set from one. A record is a reference to a string of the struct's bytes, so `$$r` is them and a record can be built from bytes C produced: `bless \$bytes, "My::Point"`. A `p` member reads the string it points to, `undef` for `NULL`. Set from Perl, it points to the record's own copy of the string, which lives as long as the record does or until the member is set again; `undef` sets `NULL`. A string C stored in the member is C's: the record never frees it. Where C moves the strings between records - an array of them it sorts, written back - each goes with the record that points to it, and a record stored into another as its member gives it copies of its own. A bare copy of the record's bytes points to the same strings but does not keep them. In a signature `{Class}` passes and returns the struct by value and `*{Class}` a pointer to it - the record's own bytes, which the callee may change in place; `undef` is `NULL`. ## Edge cases - **A class declared twice** - croaks. - **A member type a struct cannot hold here** (`s`, `P`, a handle, a pointer type, a long double or complex member) - croaks naming it.