```{index} single: Peta::FFI; Perl module ``` # Peta::FFI ```{pperl-module-badges} Peta::FFI ``` 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 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) — Call common libc functions from Perl without writing a single line of FFI glue. - [`Peta::FFI::UUID`](FFI/UUID) — Generate and parse RFC 4122 UUIDs via the system's libuuid library. ## Functions ### Library loading #### [`ffi_dlopen`](FFI/ffi_dlopen) Open a shared library and return a handle suitable for passing to `call`. #### [`ffi_dlclose`](FFI/ffi_dlclose) Release a library handle previously returned by `dlopen`. ### Function calls #### [`ffi_call`](FFI/ffi_call) Invoke a C function from an opened library and return its result. ### Symbol introspection #### [`ffi_scan`](FFI/ffi_scan) List the shared libraries the dynamic linker already knows about. ```{toctree} :hidden: :maxdepth: 1 FFI/Libc FFI/UUID FFI/ffi_dlopen FFI/ffi_call FFI/ffi_dlclose FFI/ffi_scan ```