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.