function#

Prepare a C function once and return it as a code reference.

Synopsis#

my $move_to = Peta::FFI::function($cairo, "cairo_move_to", "(odd)v");
$move_to->($cr, 10, 20);

my $validate = Peta::FFI::function($lib, "schema_validate", "(<My::Schema>p)s",
                                   free => "string_free");
my $errors = $validate->($schema, $json);

Arguments#

  • $lib, $name, $signature - as for call.

  • free => $function - the library function that frees what the callee hands over: an s result, an *s argument, an array the callee allocates (*T[r], *T[#k], *T[0]) and the strings in one, and bytes it allocates (*P[r], *P[#k]). By name (looked up in $lib) or by address. Without it these are freed with the C library’s free(), which is right for C code that allocates with malloc, and wrong for anything else - a Rust library must name its own.

  • release => $function - for an array of records the callee allocates: the library function (array, count) that frees it and whatever its records point to (libvirt’s virTypedParamsFree). It runs when the last record taken from the array is gone.

What you get back#

A code reference. Calling it with the arguments the signature lists returns what call would. The signature is parsed, the symbol resolved and the call interface prepared once, here, so each call costs only its argument and result conversion. A function whose arguments and result are integers, f, d or o - at most eight arguments, six of them integers or o, and not variadic - is also compiled into machine code of its own that calls it directly, once it has been called 8192 times, when the compile has paid for itself. PPERL_FFI_STUBS=N compiles after N calls instead, and PPERL_FFI_STUBS=0 sends every call through the general path.

The function keeps its library loaded for as long as the code reference lives, whatever dlclose is called on.

Edge cases#

  • Symbol not found, bad signature - croak here, as call would on its first use.

  • Wrong argument count - croaks with NAME: expected N args, got M, NAME being the C function’s.

  • free on a function that hands nothing over, release on one without an allocated array of records - croak.