Skip to main content

ffi.call

Functions for calling arbitrary C functions at runtime via libffi. Addresses are plain Lua numbers (doubles). All functions use a compact signature string to describe the return type and argument types: the first character is the return type, and each subsequent character is an argument type, in order.

Valid type characters: v void, i int32, u uint32, l int64, f float, d double, b uint8/bool, p pointer (number), s string (char*).

Functions

ffi.call.invoke(address, signature, ...)

Note: No crash or timeout protection. For safer calls, use `lje.call.bind` and invoke the resulting closure, which runs under a 100 ms watchdog with SEH exception handling.

Calls the C function at address immediately using the given type signature and arguments. This is a direct, unprotected call — no watchdog timer or SEH exception guard is active. If the callee crashes or hangs, the host process is affected directly.

On success the return value is pushed according to the return type character in signature: numeric types become number, b becomes boolean, s becomes string (or nothing if the pointer is NULL), and v returns nothing.

On error (unrecognised signature or libffi CIF preparation failure) a single error string is returned instead of the normal return value.

Parameters

NameTypeDescription
addressnumber

Address of the C function to call.

signaturestring

Type signature string. First character is the return type (v i u l f d b p s), remaining characters are argument types in order.

...any...

Arguments to pass to the function. Must match the argument type characters in signature in count and kind: numeric types and pointers expect number, b expects a value coerced by toboolean, and s expects a string.

Returns

TypeDescription
any?

The function's return value, marshalled to a Lua type according to the return type character, or a string error message if the signature was invalid. v (void) and a NULL s return push nothing.

ffi.call.invoke_var(address, signature, fixed_count, ...)

Note: Like `invoke`, this call is unprotected. Crashes or infinite loops in the callee will affect the host process directly.

Calls a variadic C function at address. The signature covers both fixed and variadic arguments; fixed_count tells libffi how many leading arguments are fixed (non-variadic). All argument values are still passed explicitly — fixed_count only affects how libffi builds the ABI frame.

Argument values start after address, signature, and fixed_count, so the first argument maps to the first type character in signature.

On error a single error string is returned. The same return-value marshalling rules as invoke apply.

Parameters

NameTypeDescription
addressnumber

Address of the variadic C function to call.

signaturestring

Type signature string covering all arguments (fixed + variadic). First character is the return type.

fixed_countnumber

Number of fixed (non-variadic) arguments. Must not exceed the total argument count encoded in signature.

...any...

All arguments (fixed and variadic) in order, marshalled by the corresponding type characters in signature.

Returns

TypeDescription
any?

The function's return value, marshalled to a Lua type, or a string error message on failure.

ffi.call.bind(address, signature)

Note: The watchdog fires after 100 ms and terminates the call with a `"watchdog timeout"` error string. The CIF is cached, so repeated `bind` calls with the same signature are cheap.

Creates and returns a Lua closure that calls the C function at address with the fixed type signature. The closure accepts exactly the argument count encoded in signature and can be called repeatedly without re-specifying the address or signature.

Unlike invoke, the generated closure runs under SEH exception protection and a 100 ms watchdog timer. If the callee raises a hardware exception (access violation, illegal instruction, divide-by-zero, stack overflow, etc.) or takes longer than 100 ms, the closure returns three values: false, an error description string, and the faulting address as a number. On success it returns the normal marshalled return value.

On error during binding (invalid signature or CIF preparation failure) a single error string is returned instead of a function.

Parameters

NameTypeDescription
addressnumber

Address of the C function to bind.

signaturestring

Type signature string. First character is the return type, remaining characters are argument types.

Returns

TypeDescription
function?

A closure f(...) that calls the target function. On success it returns the marshalled return value. On a hardware exception or watchdog timeout it returns false, error_string, fault_address. On binding failure a string error is returned here instead of a function.