LUA C API — слабые ссылки с luaL_ref

На следующем примере:

int r = luaL_ref(L, LUA_REGISTRYINDEX);

r будет строгой ссылкой на объект на вершине стека.

Можно ли получить слабую ссылку на верхний объект в стеке?

Один из подходов, о котором я думал, — создать таблицу со слабыми значениями и сохранить ее в глобальном реестре. Затем используйте это, когда требуется слабое значение.

Есть ли более простой подход?

Lua 2.4 имел это в документации, но luaL_ref теперь работает по-другому.:

Функция lua_ref создает ссылку на объект, который находится на вершине стека, и возвращает эту ссылку. Если lock имеет значение true, объект заблокирован: это означает, что объект не будет удален сборщиком мусора.


person Grapes    schedule 13.10.2013    source источник
comment
возможный дубликат поиска слабого реестра Lua   -  person Kamiccolo    schedule 13.10.2013
comment
@Kamiccolo Этот вопрос относится к luaL_ref. Я искал решение C API о том, как его реализовать.   -  person Grapes    schedule 13.10.2013


Ответы (1)


Это решение, которое я придумал:

int create_ref(bool weak_ref)
{
    lua_newtable(L); // new_table={}

    if (weak_ref) {
        lua_newtable(L); // metatable={}            

        lua_pushliteral(L, "__mode");
        lua_pushliteral(L, "v");
        lua_rawset(L, -3); // metatable._mode='v'

        lua_setmetatable(L, -2); // setmetatable(new_table,metatable)
    }

    lua_pushvalue(L,-2); // push the previous top of stack
    lua_rawseti(L,-2,1); // new_table[1]=original value on top of the stack

    //Now new_table is on top of the stack, rest is up to you
    //Here is how you would store the reference:
    return luaL_ref(L, LUA_REGISTRYINDEX); // this pops the new_table
}

С помощью этой функции я могу хранить слабые и сильные ссылки. Только с 1 дополнительной таблицей в качестве накладных расходов (или 1+метатаблицей для слабых ссылок).

person Grapes    schedule 13.10.2013
comment
Да, это единственный реальный способ сделать это, за исключением пользовательских значений, привязанных к значениям пользовательских данных, которые также являются слабыми. Но этот маршрут специфичен для использования объектов пользовательских данных и может не применяться в вашем случае. - person Ian; 14.10.2013