В чем разница между реестром 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. Присвоение нового неизменного значения некоторой переменной не приведет к изменению значения, хранящегося в реестре, т. Е. Реестр не будет следовать обновлениям некоторой переменной. Но с изменением содержимого изменяемого значения (таблицы и т. Д.) Все в порядке, поскольку реестр и переменная будут ссылаться на одно и то же значение.

1

Другие решения

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

Различия между Луа 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

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

  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 прямо.

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

1

По вопросам рекламы [email protected]