Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ffi.declare

import ffi.declare

ffi lifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelled ffi.declare.* needs import ffi.declare.

Declarations read from C and Rust source.

Classes

Declarations

class ffi.Declarations

A set of declarations: types, functions, variables and constants, read from any mix of C and Rust source.

Each source added sees everything added before it, and anything in the declarations it includes. Nothing is bound to a library until bind(), so one set of declarations serves any number of libraries.

var api = ffi.declarations()
  .declare('typedef struct { double x, y; } point;')
  .declare('double length(point p);')

var geometry = api.bind(ffi.open('geometry'))
echo geometry.length({ x: 3, y: 4 })
  • printable — has a @to_string(), so echo and print() show something useful

Constructor

ffi.Declarations()

Declarations.declare()

ffi.Declarations.declare(source: string)

Reads C declarations into the set, returning it for chaining.

Typedefs, structs, unions, enums, function prototypes, extern variables and _Static_asserts are read. So are object-like #defines, which become constants, and #if and its relatives, which are evaluated for this platform. #pragma pack is honoured. Including a C standard header is accepted, since everything it declares is already known; including any other file is an error, as is expanding a function-like macro.

A function returning const char * returns a string. A function with a body, as an inline helper in a header has, is read and not bound, since the library need not export it.

Parameters

  • source (string)

Returns — self

Raises DeclarationError with the line and column of the problem.

Declarations.declare_rust()

ffi.Declarations.declare_rust(source: string)

Reads Rust declarations into the set, returning it for chaining.

Functions in extern "C" blocks, and extern "C" fn definitions marked #[no_mangle] or #[export_name], are read with their bodies skipped. So are #[repr(C)], #[repr(transparent)], packed and align structs and unions, enums with #[repr(C)] or an integer #[repr] (with or without fields), type aliases, const items and extern statics. #[cfg(...)] is evaluated for this platform. Anything else, from use lines to impl blocks, is skipped, and a type may be used before it is declared.

Parameters

  • source (string)

Returns — self

Raises DeclarationError with the line and column of the problem.

Declarations.include()

ffi.Declarations.include(other)

Makes the types and constants of other usable by sources added to this set from now on, returning this set for chaining.

Parameters

  • other (Declarations)

Returns — self

Raises ValueError when that would make a set include itself.

Declarations.type()

ffi.Declarations.type(spelling: string) -> Type

A type written in C, resolved against these declarations: 'struct stat *', 'point[4]', 'int (*)(const void *, const void *)'.

Parameters

  • spelling (string)

Returns Type

Raises DeclarationError when it does not name a type.

Declarations.constant()

ffi.Declarations.constant(name: string) -> number|bigint|string|Pointer|nil

The value of a declared constant: an enum constant, a #define, or a Rust const.

A #define casting a constant to a pointer type, as a header spells a sentinel address, is a Pointer of that type at that address: ((void *) -1) is the all-ones address, and a null one is nil. Passed where C takes that pointer, it is exactly the value the C code would pass.

Parameters

  • name (string)

Returns number|bigint|string|Pointer|nil

Raises ValueError when no constant of that name was declared.

Declarations.constants()

ffi.Declarations.constants() -> dict

Every declared constant, by name, in the order declared.

Returns dict

Declarations.types()

ffi.Declarations.types() -> dict

Every named type: typedefs and Rust type names under their names, and tagged C types under their tags, such as 'struct point'.

Returns dict

Declarations.functions()

ffi.Declarations.functions() -> dict

Every declared function’s type, by name.

Returns dict

Declarations.variables()

ffi.Declarations.variables() -> dict

Every declared variable’s type, by name.

Returns dict

Declarations.bind()

ffi.Declarations.bind(library, options) -> module

Binds the declarations to library, returning a namespace.

The namespace holds a function for each declared function, a Pointer for each declared variable, each constant, and each type that has a name of its own (a typedef or a Rust type); tagged C types are reached with type(). Members are read the way a module’s are:

var sqlite = api.bind(ffi.open('sqlite3'))
echo sqlite.sqlite3_libversion()

Parameters

  • library (Library)
  • options (dict|nil) — allow_missing: when true, a declared function or variable the library does not export is left out of the namespace instead of being an error. Defaults to false.

Returns module

Raises SymbolError naming every missing symbol, unless allow_missing is set.

Declarations.to_string()

ffi.Declarations.to_string()

2026, Richard Ore and Zuri contributors