Приведенный ниже пример просто демонстрирует проблему/вопрос; на самом деле у меня есть функции, создающие и возвращающие множество различных объектов пользовательских данных, и между некоторыми из них я могу вызвать сборщик мусора Lua.
Кроме того, я использую Lua версии 5.3.3, работающую как в Windows, так и в Linux. Обработка ошибок не показана для простоты.
У меня есть класс С++, доступный для Lua через стандартные пользовательские данные, как описано, например, в «Программирование на Lua» Роберто Иерусалимского. Моя проблема в том, что я не уверен, когда в Lua есть ссылка на мой объект, поэтому когда мне разрешено вызывать сборщик мусора через функцию C++ lua_gc?
у меня например стандартный класс Foo C++ с конструктором и деструктором. И определил метатаблицу «FOO» с функцией входа __gc, называемой ReleaseFoo, как также показано.
Я создаю экземпляр в Lua с помощью следующего кода C++:
static int NewFoo(lua_State* L)
{
Foo** foo;
foo = (Foo**) lua_newuserdata(L, sizeof(Foo**));
*foo = new Foo();
luaL_getmetatable(L, "FOO");
lua_setmetatable(L, -2);
// QUESTION: Can I call lua_gc(L, LUA_GCCOLLECT, 0) here without
// risking my user data object being garbage collected.
// As I see it, Lua does not yet have a reference
// to my user data object.
return 1;
}
static int ReleaseFoo(lua_State* L)
{
Foo* foo = *(Foo**)lua_touserdata(L,1);
if (foo)
{
delete foo;
foo = NULL;
}
return 0;
}
В Lua его использование будет выглядеть так (поэтому только после возврата функции C++ NewFoo(L) ссылка устанавливается, но могу ли я вызвать сборщик мусора, как показано?):
LUA> foo = NewFoo()