### 2.5 Reusable Call Plans ¶

When the same signature is called many times – as language bindings typically do – you can build a call plan once and reuse it, so that each call avoids the work `ffi_call` would otherwise repeat on every invocation. A plan is an opaque, caller-owned object built from a prepared `ffi_cif`.

Function: ffi_call_plan * ffi_call_plan_alloc (ffi_cif *cif) ¶

  Builds and returns a reusable plan for the signature described by cif, which must already have been prepared with `ffi_prep_cif`. The plan does not copy cif; cif must remain valid for as long as the plan is used.

  Returns `NULL` only when memory cannot be allocated. A signature for which no accelerated path exists is still valid: the returned plan simply falls back to `ffi_call` when it is invoked.

Function: void ffi_call_plan_invoke (ffi_call_plan *plan, void *fn, void *rvalue, void **avalues) ¶

  Calls fn using plan. The fn, rvalue, and avalues arguments have exactly the same meaning as for `ffi_call` (see The Basics), including the rule that integral return values narrower than a register are widened to `ffi_arg`.

  A plan is immutable once built, so a single plan may be invoked concurrently from multiple threads without additional locking.

Function: void ffi_call_plan_free (ffi_call_plan *plan) ¶

  Releases a plan returned by `ffi_call_plan_alloc`. Passing `NULL` is harmless. The `ffi_cif` the plan was built from is not affected.

Function: size_t ffi_call_plan_size (ffi_call_plan *plan) ¶

  Returns the total number of bytes `libffi` allocated for plan, including any internal argument-placement data it owns. Returns zero when plan is `NULL`. The result does not include the `ffi_cif`, which the caller owns. This is intended for embedders that account for the memory held by long-lived plans and would otherwise have to guess at the size of an opaque type.