Создание анонимных переменных пользовательских данных - PullRequest
0 голосов
/ 22 октября 2018

Я работаю с lua C api для запуска скриптов, которые взаимодействуют с нативными предложениями.Я использую MOC Qt для получения информации о типе времени выполнения.До сих пор я реализовал создание, удаление и индексацию всех классов, с которыми я хочу общаться с lua.

Вот пример сценария того, что я могу сделать сейчас:

myObject = MyClass.new()  --creates new userdata
otherObject = OtherClass.new()  --creates new userdata

myObject:functionForOthers(otherObject)  --method that takes userdata as argument

В этом сценарии otherObject создается и остается в стеке.Затем он проходит через functionForOthers(), который принимает OtherClass объекты в качестве аргумента.

Но что, если я не хочу, чтобы otherObject был помещен в стек?Что, если я хотел, чтобы это была анонимная переменная, существующая только в области вызова функции?

myObject = MyClass.new()

myObject:functionForOthers(OtherClass.new())

Это все еще работает, но экземпляр OtherObject создается, но никогда не назначаетсяпеременная оставляет ее в стеке недоступной до тех пор, пока не закончится область.Это не вызывает каких-либо прямых проблем, но беспокоит часть меня, которая эффективно использует память.

У меня есть много нативного кода, обрабатывающего бэкэнд этих операций, но суть в том, что new это поле глобальных таблиц MyClass и OtherClass, которое указывает на встроенную функцию CreateObject.Оттуда экземпляр класса создается и сохраняется в пользовательских данных после вызова lua_newuserdata()

В вызове functionForOthers() используется метаметод __index, который указывает на встроенную функцию IndexObject, которая вызывает методесли он существует.

Каков основной подход к реализации анонимных переменных пользовательских данных?Я по-прежнему хочу, чтобы оба сценария были корректными, я просто хочу, чтобы объект OtherClass второго сценария оставался в области действия до завершения вызова функции.

1 Ответ

0 голосов
/ 22 октября 2018

Такое ощущение, что вы неправильно понимаете некоторые части Lua.

Передача некоторого объекта в качестве аргумента функции не "оставляет" этот объект в стеке.В стеке хранится только ссылка на объект.Другая ссылка на тот же объект хранится в переменной otherObject.Когда вы передаете переменную в качестве аргумента functionForOthers(), вы получаете эту копию, скопированную по значению в стек, и эта ссылка удаляется из стека, как только вызываемая функция возвращает управление.

Сам объект сохраняется вЛуа куча.В конечном итоге он будет уничтожен / собран, когда сборщик мусора обнаружит, что на этот объект не осталось ссылок.Объект не уничтожается в конце области, только ссылка теряется.Когда сборщик мусора действительно удалит объект, это зависит от сборщика мусора.

Если вы беспокоитесь о памяти, вы можете периодически вызывать collectgarbage().Это может заикать вашу программу на некоторое время, так что выбирайте подходящий момент.В противном случае вы можете полностью его игнорировать, просто убедитесь, что вы не собираете ссылки на объекты в какой-то долгоживущей структуре (глобальные переменные, реестр или ваши собственные словари / кеши).Ссылки на стек быстро удаляются, если вы невольно создаете очень глубокий или бесконечный рекурсивный вызов.Объект, который не может быть достигнут, будет удален автоматически, так работает сборщик мусора с метками и метками.

...