在Lua表中注册C函数。

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

点赞
用户288406
用户288406
```c++
void register_c_function(char const * const tableName, char const * const funcName, CFunctionSignature funcPointer)
{
    lua_getfield(lstate, LUA_GLOBALSINDEX, tableName);  // 将 table 推入栈中
    if (!lua_istable(lstate, -1))                       // 如果不是 table,创建之
    {
        lua_createtable(lstate, 0, 1);      // 创建新的 table
        lua_setfield(lstate, LUA_GLOBALSINDEX, tableName);  // 将其添加到全局上下文中

        // 重置栈中的 table
        lua_pop(lstate, 1);                 // 弹出栈顶的表(空值)
        lua_getfield(lstate, LUA_GLOBALSINDEX, tableName);  // 将 table 推入栈中
    }

    lua_pushstring(lstate, funcName);       // 将键推入栈中
    lua_pushcfunction(lstate, funcPointer); // 将值推入栈中
    lua_settable(lstate, -3);               // 将键值对添加到 table 中

    lua_pop(lstate, 1);                     // 弹出栈中的 table
}

```

2010-04-25 23:02:55
用户68204
用户68204

luaL_register() 的目的是为一个或多个函数创建一个模块。典型的用法是作为用 C 语言编写的模块设置的一部分:

/* 实际上 modA() 和 modB() 的定义是我们需要自己完成的 */

/* 模块中的函数列表 */
static const luaL_reg modfuncs[] =
{
    { "a", modA},
    { "b", modB},
    { NULL, NULL }
};

/* 模块加载器函数最终由 require"mod" 调用 */
int luaopen_mod(lua_State *L) {
    luaL_register(L, "mod", modfuncs);
    return 1;
}

其中 luaopen_mod() 函数创建了一个名为 "mod" 的模块,有两个名为 mod.amod.b 的函数。

引用 luaL_register(L,libname,l) 手册中的描述:

libnameNULL,则把 l 中所有函数(详见 luaL_Reg)注册到堆栈顶部的表中。

libnameNULLluaL_register() 会创建一个新的表 t,将其作为全局变量 libname 的值,也将其设置为 package.loaded[libname] 的值,并在其中注册 l 中的所有函数。如果在 package.loaded[libname] 或变量 libname 中有一个表,则重用该表,而不是创建一个新表。

无论哪种情况,该函数都会将表留在堆栈顶部。

只要将一个表置于堆栈顶部,并将 luaL_register() 的第二个参数设置为 NULL,则可以使用 luaL_register() 将 C 函数放置在任何表中。

2010-04-26 22:27:18