在 Lua C API 中插入子表的函数

我正在制作自己的游戏引擎,使用 Lua C API。我有如下的 Lua 表层级结构:

my_lib = {
  system = { ... },
  keyboard = { ... },
  graphics = { ... },
  ...
}

同时,我有一些 C 函数需要注册,例如:

inline static int lua_mylib_do_cool_things(lua_State *L) {
    mylib_do_cool_things(luaL_checknumber(L, 1));
    return 0;
}

那么,我该如何将其注册为 my_lib 子表的成员,像这样:

my_lib = {
  system = { do_cool_things, ... },
  keyboard = { ... },
  graphics = { ...}
}

现在,我只知道如何注册全局表的成员,像这样:

inline void mylib_registerFuncAsTMem(const char *table, lua_CFunction func, const char *index) {
    lua_getglobal(mylib_luaState, table);
    lua_pushstring(mylib_luaState, index);
    lua_pushcfunction(mylib_luaState, func);
    lua_rawset(mylib_luaState, -3);
}

但是对于子表,我应该怎么办呢?

点赞
用户415823
用户415823

一个在 Lua 5.1 中将多个 Lua C 函数注册到表中的简单方法是使用luaL_register

首先,实现你的 Lua 函数,它们应该采用lua_CFunction的形式。

static int graphics_draw(lua_State *L) {
    return luaL_error(L, "graphics.draw unimplemented");
}

static int system_wait(lua_State *L) {
    return luaL_error(L, "system.wait unimplemented");
}

接下来,为每个包含你的 Lua 函数和它们名称(键)的子表创建一个luaL_Reg结构。

static const struct luaL_Reg module_graphics[] = {
    {"draw", graphics_draw},
    // 在这里添加更多的图形函数...
    {NULL, NULL}  // 使用哨兵值终止列表
};

static const struct luaL_Reg module_system[] = {
    {"wait", system_wait},
    {NULL, NULL}
};

然后,在你返回模块表的函数中,创建每个子表并注册它们的函数。

int luaopen_game(lua_State *L) {
    lua_newtable(L);  // 创建模块表

    lua_newtable(L);                          // 创建图形表
    luaL_register(L, NULL, module_graphics);  // 注册函数到图形表
    lua_setfield(L, -2, "graphics");          // 将图形表添加到模块表

    lua_newtable(L);                          // 创建系统表
    luaL_register(L, NULL, module_system);    // 注册函数到系统表中
    lua_setfield(L, -2, "system");            // 将系统表添加到模块表

    // 对其他子表重复相同的过程

    return 1;  // 返回模块表
}

这将导致一个具有以下结构的模块表:

game = {
    graphics = {
        draw -- C 函数 graphics_draw
    },
    system = {
        wait -- C 函数 system_wait
    }
}
2016-04-13 18:45:16