Writing C Modules
Prerequisites: Embedding Lua in C
The same C API also works in the other direction: a C library that Lua
loads with require. It's how you add fast native code or bind an
existing C library.
// fastmath.c — build as a shared library:
// Linux: cc -O2 -shared -fPIC fastmath.c -o fastmath.so
// macOS: cc -O2 -bundle -undefined dynamic_lookup fastmath.c -o fastmath.so
#include <lua.h>
#include <lauxlib.h>
static int l_clamp(lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
lua_Number lo = luaL_checknumber(L, 2);
lua_Number hi = luaL_checknumber(L, 3);
lua_pushnumber(L, x < lo ? lo : (x > hi ? hi : x));
return 1;
}
static int l_sum(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_Integer n = luaL_len(L, 1);
lua_Number total = 0;
for (lua_Integer i = 1; i <= n; i++) {
lua_geti(L, 1, i);
total += luaL_checknumber(L, -1);
lua_pop(L, 1);
}
lua_pushnumber(L, total);
return 1;
}
static const luaL_Reg funcs[] = {
{"clamp", l_clamp},
{"sum", l_sum},
{NULL, NULL}
};
// Called by require("fastmath")
int luaopen_fastmath(lua_State *L) {
luaL_newlib(L, funcs); // create a table with the functions
return 1;
}
-- illustrative
local fastmath = require("fastmath")
print(fastmath.clamp(150, 0, 100)) --> 100.0
print(fastmath.sum({1, 2, 3.5})) --> 6.5
require("fastmath")findsfastmath.so(orfastmath.dll) throughpackage.cpathand callsluaopen_fastmath.luaL_newlibbuilds the module table from the function list.- Argument-checking helpers (
luaL_checknumber,luaL_checktype) raise clear Lua errors for bad input.
LuaJIT FFI: no C module needed
With LuaJIT, the FFI calls C functions directly from Lua:
-- illustrative
local ffi = require("ffi")
ffi.cdef[[ int abs(int x); double sqrt(double x); ]]
print(ffi.C.abs(-42), ffi.C.sqrt(2))
Package C modules as rocks (next lessons) so users can install them with LuaRocks, which compiles them for their platform.