表作为从Lua调用的C函数的参数

Table as parameter in C function called from Lua

本文关键字:函数 参数 调用 Lua      更新时间:2023-10-16

我处理Lua的时间较长,但有一点我无法实现。在从Lua调用的C函数中,我能够使用表名读取全局Lua表,如下所示:

C:

    // get table
    lua_getglobal(L, "tableName");
    if (!lua_istable(L, -1))                
       break;            
    // count entries in table
    ULONG numEntries = 0; 
    lua_pushnil(L);
    while(lua_next(L,-2))
    {
        numEntries++;
        lua_pop(L, 1);
    }

但是如果我有一个lua函数像这样调用一个C函数:

Lua:

   luaTable = { }
   luaTable.Param1 = Value1 
   luaCallC("This is a Text", luaTable)

如何访问table参数?

C:

    // get table
    // ???
    // count entries in table
    ULONG numEntries = 0; 
    lua_pushnil(L);
    while(lua_next(L,-2))
    {
        numEntries++;
        lua_pop(L, 1);
    }

CFunction的参数按其提供的顺序被压入虚拟堆栈,在操作这些值之前,只需由您执行所需的错误检查。

Lua 5.3 Manual§4.8 - lua_CFunction:

为了与Lua正确通信,C函数必须使用以下协议,该协议定义了参数和结果的传递方式:C函数以直接顺序从Lua的堆栈中接收参数(第一个参数首先被推送)。

[…)

第一个参数(如果有的话)位于索引1,最后一个参数位于索引lua_gettop(L)。要将值返回给Lua, C函数只需按直接顺序将它们压入堆栈(首先压入第一个结果),并返回结果的个数

一个使用任意第一个参数详尽检查表中元素数量的示例。

int count (lua_State *L) {
    luaL_checktype(L, 2, LUA_TTABLE);
    puts(lua_tostring(L, 1));
    
    size_t ec = 0;
    
    lua_pushnil(L);
    
    while (lua_next(L, 2)) {
        lua_pop(L, 1);
        ec++;
    }
    
    lua_pushinteger(L, (lua_Integer) ec);
    return 1;
}

在Lua中注册函数后:

count('foo', { 'a', 'b', 'c' }) -- 3