В чем разница между реестром Lua с легкими пользовательскими данными и ссылками?

Таким образом, с помощью API Lua C вы можете сохранить значение Lua в реестре и получить его позже. Существуют разные способы сделать это, вы можете создать переменную и использовать ее указатель как ключ в реестре, поскольку он всегда уникален. Вы нажимаете указатель как легкие пользовательские данные.

Вы также можете создать ссылку, используя LuaL_ref(L, LUA_REGISTRYINDEX) . В чем преимущество одного над другим? Когда использовать ссылки и когда использовать указатели?

Также со ссылками, так как это называется ссылкой, если сборщик мусора Lua собирает значение Lua, будет ли значение в реестре nil ? Что, если Lua обновит значение Lua, изменится ли значение в реестре?

Реестр Lua – это еще одна таблица lua, легко доступная через предопределенный «специальный» индекс. Думаю, вам не нужны объяснения того, как таблица Lua отличается от светлых пользовательских данных.
На самом деле не имеет значения, как вы будете индексировать таблицу реестра, если вы можете сохранить этот ключ на стороне C / C ++. Для вашего удобства уже есть функции (luaL_ref / luaL_unref), дающие вам целочисленный ключ, который легко хранить и перемещать.

О сборке мусора – правила всегда одинаковы. Пока значение хранится в таблице, которая не была помечена как слабая таблица (реестр не является слабой таблицей), это значение не будет очищено. Вы должны явно удалить значение из реестра.

Изменение значения будет соответствовать нормальным правилам Lua. Присвоение новой неизменяемой ценности некоторой переменной не изменит значение, хранящееся в реестре, то есть реестр не будет следовать обновлениям некоторой переменной. Но изменение содержимого изменчивого значения (таблица и т. Д.) В порядке, поскольку реестр и переменная будут ссылаться на одно значение.

В дополнение к предыдущему ответу:

Различия между Lua lightuserdata и userdata

lightuserdata – это особый тип Lua (а также nil , boolean , number , string , table , thread и т. д.), содержащий C-указатель. Ничего более. Вы не можете назначить lightuserdata для lightuserdata . Напротив, вы можете назначить метатебель типа userdata . Например, см. Операции Lua File , где дескриптор файла – это userdata с помощью методов. f:read("*all") f является userdata эта команда эквивалентна f.read(f, "*all")

Индексирование LUA_REGISTRYINDEX с помощью указателя integer или C

Существует два метода, которые широко используются в таблице реестра.

  1. Создайте новую ссылку на значение Lua с помощью luaL_ref и сохраните возвращаемое целочисленное значение где-нибудь в вашем коде. Т.е. для доступа к значению Lua вам нужно будет прочитать переменную C, содержащую таблицу референтных и индексных реестров с lua_rawgeti(L, LUA_REGISTRYINDEX, i) где это целочисленное значение. lua_rawseti(L, LUA_REGISTRYINDEX, i) также возможно, но не пытайтесь переписать значение nil с помощью этого метода!

  2. Вы создаете статическую переменную C static int myvar; а затем используйте lua_rawgetp(L, LUA_REGISTRYINDEX, p) и lua_rawsetp(L, LUA_REGISTRYINDEX, p) для манипулирования сохраненным значением Lua прямолинейно.

К сожалению, я не могу сравнить эффективность обоих методов. Я думаю, что они почти одинаковы.