如何检测 table 在 SWIG 类型映射中是否有字符串键

How to detect if a table has a string key in SWIG typemap

我正在尝试为以 Lua table 作为参数的函数创建 SWIG 类型映射。

这是我的类型图,可以很好地与带数字键的 table 搭配使用。

%typemap(in) (int argc, t_atom *argv)
{
    if (!lua_istable(L, $input))
        SWIG_exception(SWIG_RuntimeError, "argument mismatch: table expected");
    lua_len(L, $input);
     = static_cast<lua_Integer>(lua_tointeger(L, -1));
    if (!) SWIG_exception(SWIG_RuntimeError, "table is empty");
     = static_cast<t_atom *>(getbytes( * sizeof(t_atom)));
    for (int i = 0; i < ; ++i) 
    {
        lua_pushinteger(L, i + 1);
        lua_gettable(L, $input);
        if (lua_isboolean(L, -1)) 
        {
            [i].a_type = A_FLOAT;
            [i].a_w.w_float = static_cast<t_float>(lua_toboolean(L, -1));
        }  
        else if (lua_isnumber(L, -1)) 
        {
            [i].a_type = A_FLOAT;
            [i].a_w.w_float = static_cast<t_float>(lua_tonumber(L, -1));
        }          
        else if (lua_isstring(L, -1)) 
        {
            [i].a_type = A_SYMBOL;
            [i].a_w.w_symbol = gensym(lua_tostring(L, -1));
        }
        else 
        {
            SWIG_exception(SWIG_RuntimeError, "unhandled argument type");
        }
    }
}
%typemap(freearg) (int argc, t_atom *argv) 
{
    freebytes(,  * sizeof(t_atom));
}

但是,当函数使用字符串键需要 tables 时。 它只是打印 SWIG_RuntimeError:table is empty.

我想在打印此错误之前检测 table 是否有字符串键。

我尝试了以下条件,但没有成功:

if (lua_type(L, -2) == LUA_TSTRING)

如何正确检测 table 参数是否在 SWIG 类型映射中至少有一个字符串键?

一旦您知道 table 的长度为 0(这意味着它有零 integer 个键),你可以使用 lua_next() 获取下一个键值对。 如果它 returns 任何你知道的 tabel 至少包含一个非整数 关键。

/* table is in the stack at index 't',
 * and is known to have no integer keys
 */
lua_pushnil(L);  /* first key */
if (lua_next(L, t) != 0) {
    /* Table contains non-integer key */
    lua_pop(L, 2);  /* throw away key-value pair */
    /* Do stuff here */
}

然而,它们的键可以是 table 类型或浮点型或允许作为 键,因此如果您需要明确检查字符串键的出现 你将不得不在循环中调用 lua_next() 并检查每个的类型 返回密钥,直到找到字符串密钥或耗尽循环。

has_stringkey = false;
/* table is in the stack at index 't' */
lua_pushnil(L);  /* first key */
while (lua_next(L, t)) {
    lua_pop(L, 1);  /* throw away value */
    if (lua_type(L, -1) == LUA_TSTRING) {
        has_stringkey = true;
        lua_pop(L, 1);  /* throw away key before exit loop */
        break;
    }
}
if (has_stringkey) { /* do stuff */ }