```{index} single: ffi_call; Peta::FFI function ``` ```{index} single: Peta::FFI::ffi_call; Perl function ``` # ffi_call Invoke a C function from an opened library and return its result. ## Synopsis ```perl my $n = Peta::FFI::call($lib, "strlen", "(p)L", "hello"); # 5 my $r = Peta::FFI::call($lib, "sqrt", "(d)d", 2.0); # 1.4142... my $s = Peta::FFI::call($lib, "getenv", "(p)p", "PATH"); # /usr/bin:... Peta::FFI::call($lib, "srand", "(i)v", 42); # void return ``` ## Arguments - `$lib` — handle returned by `dlopen`. - `$func` — symbol name to look up in the library. - `$sig` — signature string `(args)ret`; see the module-level type-code table. - the remaining arguments — one value per type code in `args`, coerced to the matching C type before the call. ## What you get back A single scalar whose shape depends on the return code: - `i` / `l` / `L` — integer. - `d` / `f` — float. - `p` — the returned `const char *` copied into a Perl string; `undef` if the C function returned `NULL`. - `v` — `1`, so the call chains naturally in boolean contexts. - `P` — pointer returned as a string (same rules as `p`). ## Output buffers (`P`) When an argument position is `P`, `call` allocates a zeroed buffer sized from the scalar you pass in. If the scalar is a string, its byte length (minimum 16) is used; otherwise the numeric value of the scalar (minimum 16) is taken as the byte size. The callee receives a pointer to that buffer. The buffer is freed after the call returns — if you need to read bytes the C function wrote into it, wrap the call in a helper module such as `Peta::FFI::UUID` that knows how to recover the buffer contents. ## Edge cases - **Wrong argument count** — croaks with `Peta::FFI::call FNAME: expected N args, got M`. - **Bad signature string** — croaks with `FFI signature error: ...` describing the offending character or missing `)`. - **Symbol not found** — croaks with `Peta::FFI::call: symbol not found: FNAME` or the message reported by `dlerror`. - **Incorrect type codes** — calling a function with a signature that does not match its real prototype is undefined behaviour. Check the C header before writing the signature. - **String argument contains a null byte** — croaks with `Peta::FFI::call: CString error: ...`.