ffi
This content is for v1.0. Switch to the latest version for up-to-date documentation.
The ffi module provides foreign function interface capabilities, allowing RayQuiro programs to load native shared libraries and invoke C functions directly with automatic conversion of primitives, strings, and byte buffers.
Quick Reference
Section titled “Quick Reference”| Function | Signature | Return Type | Description |
|---|---|---|---|
ffi.load | ffi.load(path) | FFILibrary | Loads a dynamic shared library (.dll on Windows, .so on POSIX). |
ffi.sym | ffi.sym(lib, name) | bool | Checks whether a exported symbol exists in the loaded library. |
ffi.call | ffi.call(lib, name, ...args) | number | Invokes an exported C function with up to 6 arguments. |
ffi.close | ffi.close(lib) | void | Unloads the dynamic library handle. |
Usage Examples
Section titled “Usage Examples”Calling Windows API Functions
Section titled “Calling Windows API Functions”var k32 = ffi.load("kernel32.dll")if (ffi.sym(k32, "GetCurrentProcessId")) { var pid = ffi.call(k32, "GetCurrentProcessId") print("Process ID: " + pid)}ffi.close(k32)Calling Standard C Library (libc / msvcrt)
Section titled “Calling Standard C Library (libc / msvcrt)”var lib = ffi.load("msvcrt.dll")ffi.call(lib, "puts", "Hello from C puts!")ffi.close(lib)Passing Buffers to Native Functions
Section titled “Passing Buffers to Native Functions”When passing a Buffer object (created via buffer.alloc or buffer.from_string) as an argument to ffi.call, the raw memory pointer (uint8_t*) is automatically passed to the C function:
var buf = buffer.from_string("Hello C library")var lib = ffi.load("mylib.dll")ffi.call(lib, "process_data", buf, buffer.size(buf))ffi.close(lib)