在Lua表中注册C函数

时间:2010-04-25 22:16:09

标签: c++ lua lua-c++-connection

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

2 个答案:

答案 0 :(得分:20)

这是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.amod.b的函数。

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

  

libname等于时调用   NULL,它只是注册所有   列表l中的函数(请参阅luaL_Reg)   进入桌面的顶部   叠加。

     

使用非空libname调用时,   luaL_register创建了一个新表t,   将其设置为全局值   变量libname,将其设置为值   package.loaded[libname]和。{   在其上注册所有函数   列表l。如果有一张桌子   package.loaded[libname]或变量   libname,重复使用此表而不是   创造一个新的。

     

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

只要表位于堆栈的顶部,

luaL_register()就可以通过将NULL传递给第二个参数来将C函数放入任何表中。

答案 1 :(得分: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
}