Skip to content
AgileLogics
4 min read

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") finds fastmath.so (or fastmath.dll) through package.cpath and calls luaopen_fastmath.
  • luaL_newlib builds 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.