Lua userdata управление временем жизни - PullRequest
0 голосов
/ 07 июля 2019

Я помещаю указатель объекта c ++ в userdata из нескольких разных мест в моем коде c ++. Я хотел бы, чтобы lua управлял временем жизни объекта c ++ (userdata). Моя проблема в том, что теперь у меня есть несколько экземпляров пользовательских данных, указывающих на один и тот же объект c ++ в среде lua. Так что GC будет вызываться при каждом экземпляре.

Я думал, что одним из решений будет создание какой-нибудь слабой кеш-таблицы в реестре lua (LUA_REGISTRYINDEX) для сопоставления указателя объекта с фактическими данными пользователя. Затем, когда я отправляю пользовательские данные в среду, я проверяю этот кэш, чтобы увидеть, были ли пользовательские данные уже созданы, и отправляю этот экземпляр (в противном случае создайте пользовательские данные и добавьте в кеш). Таким образом, в среде существует только один экземпляр пользовательских данных.

Это лучшее решение или я что-то упустил?

1 Ответ

0 голосов
/ 07 июля 2019

Правильный ответ - прекратить делать это:

У меня есть несколько экземпляров пользовательских данных, указывающих на один и тот же объект c ++ в среде lua

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

И если у вас действительно есть набор таких функций, вам необходимо пересмотреть, должен ли Lua иметь владение этими объектами, или следует ли им просто пользоваться ими.Вы будете удивлены, как редко вам действительно нужно передать право собственности на объекты Lua.

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

В C ++ это пишется shared_ptr.Следовательно, ваши пользовательские данные должны хранить shared_ptr<T> для управляемого объекта.GC должен уничтожить shared_ptr, который уничтожит управляемый T только в том случае, если все остальные экземпляры shared_ptr, которые имеют с ним право собственности, были уничтожены.

...