代码之家  ›  专栏  ›  技术社区  ›  Zack Lee

使用luaL\u ref获取对表中用户数据的引用?

  •  2
  • Zack Lee  · 技术社区  · 6 年前

    首先,我为没有上传完整的代码而道歉。

    我在试着改变 userdata pointer 因此可以使用 lua_rawgeti() .

    如果你看到 outletRet() 函数,它检查返回值的类型,如果是 outlet_pointer() 而且看起来效果不错。

    如果 在一个 table outletTable() 函数被调用。如果其中一个元素是 用户数据 用户数据 指针 然后通过调用 .

    但是,什么时候 luaL_ref(L, LUA_REGISTRYINDEX) 桌子 不仅仅是 用户数据 在里面。

    我怎样才能得到 而不是全部

    void ofLua::outletTable() //called from outletRet() below
    {
        lua_pushvalue(L, -1);
        lua_pushnil(L);
        int ac = 0;
        t_atom *av = static_cast<t_atom *>(getbytes(sizeof(t_atom) * ac));
        while (lua_next(L, -2))
        {
            av = static_cast<t_atom *>(resizebytes(av, sizeof(t_atom) * ac,
                                                   sizeof(t_atom) * (ac + 1)));
            if (lua_isboolean(L, -1))
            {
                av[ac].a_type = A_FLOAT;
                av[ac].a_w.w_float = static_cast<t_float>(lua_toboolean(L, -1));
            }
            else if (lua_isnumber(L, -1))
            {
                av[ac].a_type = A_FLOAT;
                av[ac].a_w.w_float = static_cast<t_float>(lua_tonumber(L, -1));
            }
            else if (lua_isstring(L, -1))
            {
                av[ac].a_type = A_SYMBOL;
                av[ac].a_w.w_symbol = gensym(lua_tostring(L, -1));
            }
            else if (lua_isuserdata(L, -1))
            {
                av[ac].a_type = A_POINTER;
            }
            ac++;
            lua_pop(L, 1);
        }
        lua_pop(L, 1);
        const ofeliaIO &io = dataPtr->io;
        if (io.hasMultiControlOutlets)
        {
            int last = (io.numOutlets >= ac ? ac : io.numOutlets) - 1;
            for (int i = last; i >= 0; --i)
            {
                if (av[i].a_type == A_FLOAT)
                    outlet_float(io.outlets[i], av[i].a_w.w_float);
                else if (av[i].a_type == A_SYMBOL)
                    outlet_symbol(io.outlets[i], av[i].a_w.w_symbol);
                else if (av[i].a_type == A_POINTER)
                {
                    userDataRefVec.push_back(luaL_ref(L, LUA_REGISTRYINDEX));
                    outlet_pointer(io.outlets[i], reinterpret_cast<t_gpointer *>(&userDataRefVec.back()));
                    luaL_unref(L, LUA_REGISTRYINDEX, userDataRefVec.back());
                    userDataRefVec.pop_back();
                }
            }
        }
        else
            outlet_list(dataPtr->ob.ob_outlet, &s_list, ac, av);
        freebytes(av, sizeof(t_atom) * ac);
    }
    
    void ofLua::outletRet()
    {
        const ofeliaIO &io = dataPtr->io;
        if (!io.hasControlOutlet) return;
        if (lua_isnil(L, -1))
            outlet_bang(io.outlets[0]);
        else if (lua_isboolean(L, -1))
            outlet_float(io.outlets[0], static_cast<t_float>(lua_toboolean(L, -1)));
        else if (lua_isnumber(L, -1))
            outlet_float(io.outlets[0], static_cast<t_float>(lua_tonumber(L, -1)));
        else if (lua_isstring(L, -1))
            outlet_symbol(io.outlets[0], gensym(lua_tostring(L, -1)));
        else if (lua_isuserdata(L, -1))
        {
            userDataRefVec.push_back(luaL_ref(L, LUA_REGISTRYINDEX));
            outlet_pointer(io.outlets[0], reinterpret_cast<t_gpointer *>(&userDataRefVec.back()));
            luaL_unref(L, LUA_REGISTRYINDEX, userDataRefVec.back());
            userDataRefVec.pop_back();
        }
        else if (lua_istable(L, -1))
            outletTable();
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Vlad    6 年前

    我正在尝试将用户数据转换为指针

    不能通过指向Lua userdata对象数据区域的指针来检索它。

    luaL_ref() ,并使用返回的整数作为引用。稍后,您可以从注册表中检索该对象,并在需要时获取指向其数据区域的指针。但不要只存储指针。

    必须在栈顶。但现在唯一留在Lua栈顶上的就是桌子。复制该表的值以进行迭代 while(lua_next()) ,从该循环中的表中读取的任何内容都会从循环末尾的堆栈中弹出。

    也许你甚至不应该建造 av 如果你真的需要的话 影音 ,然后保存 luaL\ U ref() lua_rawgeti() 获取userdata对象,处理后可以取消引用它。

    推荐文章