Как синхронизировать сборку мусора в Lua и C ++ - PullRequest
4 голосов
/ 02 сентября 2011

Я пытаюсь встроить lua в существующее приложение C ++ и создал для него стандартную процедуру, наследуя от класса, который выполняет эту работу. Серьезная проблема, которую я вижу, состоит в том, что если открытый объект освобождается или удаляется в среде C ++, то вызов Lua вызовет сбои. Если память удаляется программой с помощью «delete», то я могу написать обертку на delete, чтобы также позаботиться об освобождении памяти в Lua, но если память была выделена C ++ и освобождена, когда соответствующая переменная выходит за рамки видимости Я не вижу пути, как это выяснить, а затем предпринять соответствующие действия в пространстве Луа, у кого-нибудь есть какие-нибудь идеи на этот счет?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 03 сентября 2011

В общем, практически каждая обертка Lua имеет какой-то способ решить, кому принадлежит какая память.То есть принадлежит ли объект Lua (или, следовательно, будет удален) Lua или вашим приложением.

Если вы указали Lua указатель на объект, которым владеет C ++, вы должны найти способубедитесь, что Lua не использует этот указатель после точки, где C ++ удаляет его.Есть несколько способов избежать этого.Одним из способов является передача права собственности на Lua.

Другим способом является использование boost/std::shared_ptr, которое позволяет делиться владением между C ++ и Lua.Если вы делаете это вручную, то вы создаете некоторые несветлые пользовательские данные размером в shared_ptr в Lua.Вы присоединяете к нему метаметод очистки, который уничтожит shared_ptr, и вы используете place-new для создания shared_ptr для пользовательских данных Lua.Luabind на самом деле имеет эту встроенную функцию: если вы передаете Lua shared_ptr, то оба они совместно владеют памятью.

Вы также можете использовать boost/std::weak_ptr.Это объект, который вы запрашиваете, чтобы получить shared_ptr.Идея в том, что вы не должны держать указатель вокруг;вы запрашиваете его временно по мере необходимости, но вы сохраняете только weak_ptr постоянно.Если объект потерял все свои shared_ptr ссылки, то запрос weak_ptr вернет нулевой указатель.

1 голос
/ 02 сентября 2011

Отказ от ответственности: я написал библиотеку, которую я собираюсь рекомендовать

Вы можете попробовать использовать эту LuaWrapper Библиотека, которая звучит так, как будто она будет обрабатывать то, что вы пытаетесь сделать,Это даже не библиотека, это просто один заголовочный файл.

Вы можете использовать luaW_push<MyType>(L, myObj);, чтобы подтолкнуть ваши объекты в Lua.Lua не будет владеть объектами, которые вы создаете из C ++, если вы не запустите на них luaW_hold<MyType>.Другими словами, если вы не скажете Lua, он не будет собирать мусор для вашего объекта.

И наоборот, вы можете использовать MyType.new() в своем коде Lua для создания объекта, которым Lua владеет .Это будет сбор мусора, как и следовало ожидать.Если вы хотите передать владение C ++, вы можете вызвать luaW_release<MyType> для вашего объекта.

Есть также такие функции, как luaW_to<MyType> и luaW_check<MyType>, и в ограниченной степени он корректно поддерживает наследование от базовых типов (хотя на данный момент он допускает только одиночное наследование).Я считаю, что это значительно упрощает мои собственные попытки совместного использования C ++ и Lua, потому что это делает управление владением указателем очень простым.

1 голос
/ 02 сентября 2011

Вам придется использовать оболочку RAII, которая может связываться с экземпляром Lua с помощью реестра и предоставлять значения Lua с помощью таблицы - вы можете удалить из нее внутренний указатель, когда закончите.

template<typename T> class LuaExposedValue {
    T t;
    lua_State* ls;
public:
    LuaExposedValue(lua_State* L) {
        // set registry[&t] = { &t }
        ls = L;
    }
    ~LuaExposedValue() {
        // remove &t from the table
    }
}

В качестве альтернативы, просто запретите Lua доступ к нему после того, как переменная исчезнет, ​​и позвольте сценаристу беспокоиться об этом.

Наконец, вы можете просто выделить все, к чему Lua может получить доступ с помощью Lua GC.

...