```{index} single: call (Peta::FFI) ``` ```{index} single: Peta::FFI::call ``` # 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: ...`.