В чем разница между реестром Lua и легкими пользовательскими данными и ссылками?
Таким образом, с помощью Lua C API вы можете сохранить значение Lua в реестре и получить его позже. Есть разные способы сделать это, вы можете создать переменную и использовать ее указатель в качестве ключа в реестре, поскольку он всегда уникален. Вы бы нажали указатель как легкие пользовательские данные.
Вы также можете создать ссылку, используя LuaL_ref(L, LUA_REGISTRYINDEX)
, В чем преимущество одного над другим? Когда использовать ссылки, а когда использовать указатели?
Также со ссылками, как это называется ссылкой, если сборщик мусора Lua собирает значение Lua, будет ли значение в реестре nil
? Что если Lua обновит значение Lua, изменится ли значение в реестре?
2 ответа
Реестр Lua - это просто еще одна таблица lua, легко доступная через предопределенный "специальный" индекс. Я думаю, вам не нужны объяснения того, как таблица Lua отличается от легких пользовательских данных.
Неважно, как вы будете индексировать таблицу реестра, если вы можете хранить этот ключ на стороне C/C++. Для вашего удобства уже есть функции (luaL_ref/luaL_unref), предоставляющие вам целочисленный ключ, который легко хранить и перемещать.
Насчет сборки мусора - правила всегда одинаковы. Пока значение хранится в таблице, которая не была помечена как слабая таблица (реестр не является слабой таблицей), это значение не будет очищено. Вы должны явно удалить значение из реестра.
Изменение значения будет подчиняться нормальным правилам Lua. Присвоение нового неизменного значения некоторой переменной не приведет к изменению значения, хранящегося в реестре, т.е. реестр не будет следовать обновлениям какой-либо переменной. Но с изменением содержимого изменяемого значения (таблицы и т. Д.) Все в порядке, поскольку реестр и переменная будут ссылаться на одно и то же значение.
В дополнение к предыдущему ответу:
Различия между Луа lightuserdata
а также userdata
lightuserdata
это особый тип Lua (а также nil
, boolean
, number
, string
, table
, thread
и т.д.), содержащий указатель C. Ничего более. Вы не можете назначить метатабельный для lightuserdata
, Наоборот, вы можете назначить userdata
тип. Например, см. Операции с файлами Lua, где описатель файла userdata
с методами. f:read("*all")
е есть userdata
команда эквивалентна f.read(f, "*all")
индексирование LUA_REGISTRYINDEX
с целым или указателем C
Есть два метода, которые широко используются в таблице реестра.
Создать новую ссылку на значение Lua с
luaL_ref
и сохраните возвращаемое целое значение где-нибудь в вашем коде. То есть, чтобы получить доступ к значению Lua, вам нужно прочитать переменную C, содержащую таблицу ссылок и реестра сlua_rawgeti(L, LUA_REGISTRYINDEX, i)
где это целочисленное значениеlua_rawseti(L, LUA_REGISTRYINDEX, i)
также возможно, но не пытайтесь переписать значение nil с помощью этого метода!Вы создаете статическую переменную C
static int myvar;
а затем использоватьlua_rawgetp(L, LUA_REGISTRYINDEX, p)
а такжеlua_rawsetp(L, LUA_REGISTRYINDEX, p)
для манипулирования хранимым значением Lua прямо.
К сожалению, я не могу сравнить производительность обоих методов. Я думаю, что они почти одинаковы.