Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register C function in Lua table

How to register a C function in Lua, but not in a global context, but as a table field?

like image 443
topright gamedev Avatar asked Apr 25 '10 22:04

topright gamedev


2 Answers

This is what luaL_register() is intended to do, for one or more functions. The canonical usage is as part of the setup for a module written in C:

/* actual definitions of modA() and modB() are left as an exercise. */

/* list of functions in the module */
static const luaL_reg modfuncs[] =
{
    { "a", modA},
    { "b", modB},
    { NULL, NULL }
};

/* module loader function called eventually by require"mod" */  
int luaopen_mod(lua_State *L) {
    luaL_register(L, "mod", modfuncs);
    return 1;
}

where this creates a module named "mod" that has two functions named mod.a and mod.b.

Quoting the manual for luaL_register(L,libname,l):

When called with libname equal to NULL, it simply registers all functions in the list l (see luaL_Reg) into the table on the top of the stack.

When called with a non-null libname, luaL_register creates a new table t, sets it as the value of the global variable libname, sets it as the value of package.loaded[libname], and registers on it all functions in the list l. If there is a table in package.loaded[libname] or in variable libname, reuses this table instead of creating a new one.

In any case the function leaves the table on the top of the stack.

luaL_register() can be used to put C functions in any table by passing NULL for its second parameter as long as the table is on the top of the stack.

like image 111
RBerteig Avatar answered Nov 07 '22 03:11

RBerteig


void register_c_function(char const * const tableName, char const * const funcName, CFunctionSignature funcPointer)
{
    lua_getfield(lstate, LUA_GLOBALSINDEX, tableName);  // push table onto stack
    if (!lua_istable(lstate, -1))                       // not a table, create it
    {
        lua_createtable(lstate, 0, 1);      // create new table
        lua_setfield(lstate, LUA_GLOBALSINDEX, tableName);  // add it to global context

        // reset table on stack
        lua_pop(lstate, 1);                 // pop table (nil value) from stack
        lua_getfield(lstate, LUA_GLOBALSINDEX, tableName);  // push table onto stack
    }

    lua_pushstring(lstate, funcName);       // push key onto stack
    lua_pushcfunction(lstate, funcPointer); // push value onto stack
    lua_settable(lstate, -3);               // add key-value pair to table

    lua_pop(lstate, 1);                     // pop table from stack
}
like image 27
topright gamedev Avatar answered Nov 07 '22 03:11

topright gamedev