```{index} single: function (Peta::FFI) ``` ```{index} single: Peta::FFI::function ``` # function Prepare a C function once and return it as a code reference. ## Synopsis ```perl 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", "(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.