Удалить все мои пользовательские данные Lua в C ++ - PullRequest
1 голос
/ 07 февраля 2012

Мне интересно, возможно ли получить доступ ко всем "таблицам" пользовательских данных (они называются таблицами пользовательских данных?), А затем удалить их из Lua, потому что это моя проблема:

a = Object(5, 5)
a:Delete()
a:SetPosition(3,3)

Как вы можете видеть сначала, я создаю объект и сохраняю указатель на класс c ++ с именем Object, который выделяется с помощью «new» в моем классе карты. Затем я удаляю объект, что означает, что я удаляю выделенную память для указателя в моем классе карты. И наконец, я вызываю SetPosition, если память все еще выделена для класса объектов C ++, все будет работать весело. Но если он удаляется (как в этом случае, потому что мы вызывали Delete () перед вызовом SetPosition (...)), моя программа потерпит крах. Итак, мне интересно следующее:

Можно ли установить переменное 'a' в lua на ноль, вызвав Delete? Я знаю, что могу сделать что-то вроде «a = a: Delete ()», если Delete вернет nil, но если я забуду выполнить часть «a =», это не удастся. Также мне интересно, можно ли удалить пользовательские данные и проверить, не существует ли их, когда я вызываю SetPositon (), если нет, я просто вернусь.

Кроме того, базовый код: http://lua -users.org / wiki / SimpleCppBinding

Ответы [ 3 ]

4 голосов
/ 07 февраля 2012

Во-первых, позвольте мне ответить на ваш вопрос:

Можно ли установить переменное 'a' в lua на ноль, вызвав Delete?

Нет.Нет средств делать то, что ты говоришь.И для этого есть причина: то, что вы пытаетесь сделать, это ужасный код.

Lua - это система сбора мусора .Не следует ожидать, что Lua удалит объектов.Если Lua получает указатель на какой-то внешний объект, то либо ваш код владеет им, либо Lua владеет им.

Если ваш код владеет им, Lua не должна его удалять.Луа может использовать в течение некоторого периода времени.Но ваш код Lua должен использовать его точно и только в течение этого периода времени.Когда время его жизни истекло, Lua не должна больше с ним разговаривать.

Это ничем не отличается от работы с указателями на объекты в C и C ++.Если вашей функции передается голый указатель (т. Е. Не умный указатель), ваш код должен знать, как долго он может разумно ожидать общения с этим объектом.Это может сохранить это?Как долго он может хранить указатель на этот объект?Когда этот объект умрет, и кто несет ответственность за его уничтожение?

Если вы передаете объект Lua таким образом, что Lua теперь владеет объектом, Lua также не должен явно удалять его.Lua - это система сбора мусора;Вы должны прикрепить метаметод __gc к вашему типу, чтобы сборщик мусора Lua вызывал ваш код при сборе пользовательских данных.Таким образом, вы можете вызывать деструкторы, свободную память и т. Д.

Когда вы даете Lua что-то, что теперь принадлежит Lua, оно должно выглядеть как обычный объект Lua.Вы не вызываете Delete методы для таблиц и строк, которые вы создаете в Lua;Вы позволяете сборщику мусора делать свою работу.Ваша задача, как написания интерфейса C ++ - to Lua, заключается в том, чтобы гарантировать, что объекты, которые вы передаете Lua, ведут себя так, как этого хочет Lua .

В случаях, когдавам нужно выполнить значительное управление ресурсами, когда вы хотите, чтобы Lua высвободил ресурсы как можно быстрее (например, для файловых дескрипторов и т. д.), а затем вам нужно сохранить указатель на ваш объект C ++ внутри не-легкие пользовательские данные.Это указатель, который вы NULL.Все ваши интерфейсные функции этого объекта будут проверять указатель, чтобы определить, является ли он пустым, и просто ничего не делать или выдавать ошибку.

Дескрипторы файла Lua (возвращаемые io.open) являются хорошим примером этого.Если вы попытаетесь вызвать на них функции, Lua выдаст ошибку Lua.

3 голосов
/ 07 февраля 2012

В методе Delete установите для метатаблицы полученного объекта значение nil, и вы получите сообщение об ошибке, если позже вызовете метод этого объекта.

1 голос
/ 07 февраля 2012

Я бы посоветовал использовать SWIG или LuaBind , вместо этого они уже позаботились о таких ловушках для вас.

...