2015-03-06 1 views
1

У меня есть ситуация, когда мне нужно сохранить ссылку на объект Ruby (экземпляр VALUE) SOLELY из C struct; т. е. объект Ruby создается и передается в библиотеку C.Удерживайте объект Ruby из библиотеки C, избегая сбора мусора

В настоящее время объект Ruby остается действительным до тех пор, как где-то в моем приложении Ruby, что-то еще ссылается на объект. Но как только единственная ссылка на объект хранится в C-структуре, сбор мусора пожинает его, поскольку mark-and-sweep больше не может его найти.

Мне нужен способ сохранить такие объекты в живых; т. е. я хочу, чтобы они жили до тех пор, пока не будет выпущена C-структура или ссылка на объект не будет удалена.

+2

В принципе, назовите 'rb_gc_mark'. , , но как настроить это зависит от вашей существующей интеграции C/Ruby. Не могли бы вы отобразить соответствующий код? Самая важная часть - это то, как вы настраиваете объект. Используете ли вы 'Data_Wrap_Struct' для создания Ruby-доступной ссылки на C-структуру? –

+0

Вы можете увидеть код, над которым я работаю [здесь] (http://github.com/mcpierce/Proton/tree/PROTON-799-Ruby-engine-apis) в каталоге proton-c/bindings/ruby. Наш проект использует Swig для генерации большей части привязок, с возможностью добавления дополнительных бит через файл ruby.i в каталог рубинового языка. – mcpierce

+0

К сожалению, я не уверен, как внести необходимые изменения в проект Swig, хотя я подозреваю, что это то же самое, и Swig вполне может создать функцию, которую вам нужно будет отредактировать. Кроме того, я не уверен, что кто-то посмотрит весь ваш проект, чтобы выяснить, как вам помочь. Чтобы предотвратить эту блокировку, добавьте в вопрос релевантную информацию и код (есть ссылка * edit * только под списком тегов). –

ответ

0

Простите, что прошло некоторое время с тех пор, как я продолжил это. В конце.

Я попытался привязать объект Ruby к оболочке Swig для структуры C, но Swig не гарантирует, что эти обертки будут идемпотентными. IOW, если я получил оболочку для структуры C, а затем попросил другую ссылку на ту же структуру, две оболочки были разными объектами и не приравнивались.

Кроме того, если объект-оболочка Swig выходит за пределы области видимости, даже если структура C не является GC'd, ссылка исчезнет, ​​и мой объект Ruby также получит полезную информацию.

В конце концов, решение заключалось в создании хэша Ruby и подключении к событиям жизненного цикла библиотеки C; то есть, когда структура C, которая ссылается на объект Ruby, является GC'd, затем удаляет объект Ruby из хеша.

В конце концов, это был единственный способ сделать это.