Skip to content

ffi

Call native code. Installed with memory by the ffi capability; nil unless granted. arm64 only.

ffi.call(target: pointer|integer, signature: string, ...): any

Argument Type Description
target pointer or integer The callee address.
signature string "<ret>(<args>)", one char per slot (see below).
The arguments, one per arg char.

Calls target. pointer:call(signature, ...) is the same call with the pointer as target.

"<ret>(<args>)", one character per slot:

Char Class Meaning
v void
i integer int64
u integer uint64
p integer pointer / address
b integer bool
s integer C string (a Lua string is marshalled to a const char* valid for the call)
f float float
d float double

Returns follow the return char: v gives nil; i/u/p give an integer or pointer (p gives a pointer userdata); f/d give a number; b gives a bool; s reads the returned char* into a Lua string.

Enforced: at most 8 integer-class arguments (i u p b s) and 8 float-class arguments (f d). No struct-by-value, no variadic functions. This is the AAPCS64 fixed-prototype limit (x0-x7, d0-d7).

ffi.pointer(n: integer): pointer

Alias of memory.at, familiar from gamesense.

-- call an exported function: int foo(const char*, double)
local foo = memory.symbol("libgame.so", "foo")
local result = ffi.call(foo, "i(sd)", "hello", 3.5)