11

如何在 Lua 中注册一个 C 函数,但不是在全局上下文中,而是作为表字段?

4

2 回答 2

21

对于一个或多个功能,这luaL_register()是打算做的。规范用法是用 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;
}

这将创建一个名为“mod”的模块,该模块具有两个名为mod.a和的函数mod.b

引用手册luaL_register(L,libname,l)

当使用libnameequal to 调用时NULL,它只是将列表l(参见luaL_Reg)中的所有函数注册到堆栈顶部的表中。

当使用非 null 调用时libnameluaL_register创建一个新表t,将其设置为全局变量的值libname,将其设置为 的值package.loaded[libname],并在其上注册列表中的所有函数l。如果变量中 package.loaded[libname]或变量 中存在表libname,则重用此表而不是创建新表。

在任何情况下,该函数都会将表格留在堆栈顶部。

luaL_register()NULL只要表位于堆栈顶部,就可以通过传递其第二个参数来将 C 函数放入任何表中。

于 2010-04-26T22:27:18.577 回答
5
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
}
于 2010-04-25T23:02:55.117 回答