# Peta::FFI
📦 std
Call C library functions from Perl without writing XS or a binding crate.
`Peta::FFI` is the dynamic FFI layer pperl ships for reaching into
shared libraries at runtime. You open a library with `dlopen`, call
any of its exported functions through `call` by giving a type
signature string, and release the handle with `dlclose`. A fourth
helper, `scan`, enumerates the shared libraries the dynamic linker
already knows about, which is useful for finding the right `soname`
before you open it.
Reach for this module when:
- The function you need lives in a system library (`libm`, `libc`,
`libuuid`, `libcrypto`) and writing a full XS binding is more
ceremony than the problem deserves.
- You already know the C prototype and want a one-liner, not a
build step.
- You are prototyping against a third-party `.so` and will decide
later whether to graduate to a proper binding.
It is **not** a replacement for XS when you need callbacks from C
back into Perl, struct layouts beyond scalars, or automatic header
parsing. For those, write an XS module.
The two sibling modules `Peta::FFI::Libc` and `Peta::FFI::UUID` are
pre-baked convenience wrappers built on top of this layer — they
handle the `dlopen` / `call` / `dlclose` dance for you for a fixed
set of functions. If your need is covered by one of them, prefer it
over hand-rolled FFI.
## Signature strings
Every `call` takes a signature string of the form `(args)ret`, where
each position is one single-character type code:
| Code | C type | Perl side |
|--------|----------------------------|-------------------------------|
| `v` | `void` | return only; `1` is returned |
| `i` | `int` | integer |
| `l` | `long` | integer |
| `L` | `unsigned long` / `size_t` | integer |
| `d` | `double` | float |
| `f` | `float` | float |
| `p` | `const char *` | input string |
| `P` | mutable buffer | output buffer, auto-allocated |
A signature with no arguments is written `()ret`, e.g. `()i` for an
int-returning no-arg function. `P` allocates a zeroed buffer big
enough for the passed scalar and hands the pointer to the callee —
typical use is for functions like `uuid_generate` that write into a
caller-supplied buffer.
## Synopsis
```none
use Peta::FFI;
my $libm = Peta::FFI::dlopen("libm.so.6");
my $root = Peta::FFI::call($libm, "sqrt", "(d)d", 2.0);
Peta::FFI::dlclose($libm);
print $root, "\n"; # 1.4142135623731
```
## Modules
- [`Peta::FFI::Libc`](FFI/Libc.md) — Call common libc functions from Perl without writing a single line of FFI glue.
- [`Peta::FFI::UUID`](FFI/UUID.md) — Generate and parse RFC 4122 UUIDs via the system’s libuuid library.
## Functions
### Library loading
#### [`ffi_dlopen`](FFI/ffi_dlopen.md)
Open a shared library and return a handle suitable for passing to `call`.
#### [`ffi_dlclose`](FFI/ffi_dlclose.md)
Release a library handle previously returned by `dlopen`.
### Function calls
#### [`ffi_call`](FFI/ffi_call.md)
Invoke a C function from an opened library and return its result.
### Symbol introspection
#### [`ffi_scan`](FFI/ffi_scan.md)
List the shared libraries the dynamic linker already knows about.