@eryx/_ffi Module

Foreign Function Interface for Luau.

Loads native shared libraries (DLLs) at runtime and invokes their exported C functions directly from Luau. Values are marshalled through typed ForeignValue wrappers to ensure correct ABI alignment.

:::note Optional capability This module is a typed facade over a platform-specific native backend. On unsupported platforms, require("@eryx/_ffi") fails immediately with a clear capability error. :::

Caution

This is a low-level API. Incorrect type declarations or pointer arithmetic will crash the process - there are no safety nets once you cross the FFI boundary.

local ffi = require("@eryx/_ffi")

local user32 = ffi.loadLibrary("user32.dll")
local msgBox = user32:getFunction(
	"MessageBoxA",
	ffi.i32,
	{ ffi.u64, ffi.str:pointer(), ffi.str:pointer(), ffi.u32 }
)

local title = ffi.str("Hello from Luau!")
local body  = ffi.str("It works!")
msgBox(ffi.u64(0), body:pointer(), title:pointer(), ffi.u32(0))

Summary

Functions

_ffi.void:pointer()ForeignType
_ffi.void.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.char:pointer()ForeignType
_ffi.char.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.str:pointer()ForeignType
_ffi.str.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.u8:pointer()ForeignType
_ffi.u8.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.u16:pointer()ForeignType
_ffi.u16.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.u32:pointer()ForeignType
_ffi.u32.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.u64:pointer()ForeignType
_ffi.u64.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.i8:pointer()ForeignType
_ffi.i8.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.i16:pointer()ForeignType
_ffi.i16.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.i32:pointer()ForeignType
_ffi.i32.__call(self: ForeignType, initialValue: any?)ForeignValue
_ffi.i64:pointer()ForeignType
_ffi.i64.__call(self: ForeignType, initialValue: any?)ForeignValue

API Reference

Functions

_ffi.loadLibrary

Loads a native shared library (DLL) by file name or path.

The library is kept loaded until the returned ForeignLibrary is garbage-collected.

local kernel32 = _ffi.loadLibrary("kernel32.dll")
_ffi.loadLibrary(path: string)ForeignLibrary

Parameters

path: string

The file name or full path of the library to load.

Returns

A handle to the loaded library.

void

_ffi.void:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.void:pointer()ForeignType

Returns

The pointer-to type.

_ffi.void.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.void.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

char

_ffi.char:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.char:pointer()ForeignType

Returns

The pointer-to type.

_ffi.char.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.char.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

str

_ffi.str:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.str:pointer()ForeignType

Returns

The pointer-to type.

_ffi.str.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.str.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

u8

_ffi.u8:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.u8:pointer()ForeignType

Returns

The pointer-to type.

_ffi.u8.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.u8.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

u16

_ffi.u16:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.u16:pointer()ForeignType

Returns

The pointer-to type.

_ffi.u16.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.u16.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

u32

_ffi.u32:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.u32:pointer()ForeignType

Returns

The pointer-to type.

_ffi.u32.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.u32.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

u64

_ffi.u64:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.u64:pointer()ForeignType

Returns

The pointer-to type.

_ffi.u64.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.u64.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

i8

_ffi.i8:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.i8:pointer()ForeignType

Returns

The pointer-to type.

_ffi.i8.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.i8.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

i16

_ffi.i16:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.i16:pointer()ForeignType

Returns

The pointer-to type.

_ffi.i16.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.i16.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

i32

_ffi.i32:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.i32:pointer()ForeignType

Returns

The pointer-to type.

_ffi.i32.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.i32.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

i64

_ffi.i64:pointer

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

_ffi.i64:pointer()ForeignType

Returns

The pointer-to type.

_ffi.i64.__call

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

_ffi.i64.__call(self: ForeignType, initialValue: any?)ForeignValue

Parameters

initialValue: any?

An optional initial value.

Returns

The newly created value.

Types

ForeignLibrary

A loaded native shared library (DLL).

Obtained via loadLibrary. The library remains loaded until the value is garbage-collected.

type ForeignLibrary = { getFunction: ( self: ForeignLibrary, name: string | number, retType: ForeignType, argTypes: { ForeignType } )ForeignFunction }
ForeignLibrary:getFunction(name: string | number, retType: ForeignType, argTypes: { ForeignType })ForeignFunction

Looks up an exported function by name or ordinal and returns a callable ForeignFunction.

ForeignFunction

A resolved native function that can be called from Luau.

Calling the function with the correct number and types of arguments returns a ForeignValue containing the return value.

type ForeignFunction = { __call: ((self: ForeignFunction, ...any) → ForeignValue) }
ForeignFunction.__call(self: ForeignFunction, ...: any)ForeignValue

Invokes the native function.

Arguments may be ForeignValue userdata or plain Luau values that are automatically converted according to the declared argument types.

ForeignType

A C type descriptor (e.g. u32, str, i64).

Type objects are callable - invoking one creates a new ForeignValue of that type, optionally initialised with a value.

local n = ffi.u32(42)   -- create a u32 with value 42
local s = ffi.str("hi") -- create a string value
type ForeignType = { pointer: ((self: ForeignType) → ForeignType), __call: ((self: ForeignType, initialValue: any?) → ForeignValue) }
ForeignType:pointer()ForeignType

Returns a new ForeignType representing a pointer to this type.

Can be chained: ffi.u32:pointer():pointer() yields u32**.

ForeignType.__call(self: ForeignType, initialValue: any?)ForeignValue

Creates a new ForeignValue of this type.

If initialValue is provided it is used to initialise the value; otherwise the memory is zero-filled.

ForeignValue

A boxed C value that can be read, written, and passed across the FFI boundary.

Pointer values can be dereferenced with get() or turned into a pointer with pointer().

type ForeignValue = { get: ((self: ForeignValue, dereference: boolean?) → any), set: ((self: ForeignValue, value: any) → ForeignValue), pointer: ((self: ForeignValue) → ForeignValue) }
ForeignValue:get(dereference: boolean?)any

Reads the value.

For scalar types this returns the corresponding Luau primitive (number or string). For pointer types this dereferences the pointer and returns a new ForeignValue one indirection level lower.

ForeignValue:set(value: any)ForeignValue

Overwrites the stored value.

Only valid for non-pointer scalar types. Returns self for method chaining.

ForeignValue:pointer()ForeignValue

Returns a new ForeignValue that is a pointer to this value.

The returned pointer does not own the memory - the original value must be kept alive for the pointer to remain valid.