Расширение Ruby C: есть ли способ завершить?

Я просмотрел все документы по расширениям Ruby C, которые не могу найти хорошего конца.

Есть ли дополнение к Init_... метод инициализации расширения C, который вызывается при выходе из интерпретатора?

2 ответа

Решение

Там нет общего крюка "выход интерпретатора". Но Ruby выполняет сборку мусора при обычном выходе, включая объекты Module и Class, и существует способ перехватить сборку мусора объектов. Таким образом, вы можете адаптировать следующий код, который в равной степени применяется к интерпретируемым объектам Ruby или объектам, определенным библиотекой C:

module MyLib
end

ObjectSpace.define_finalizer( MyLib, proc { puts "MyLib unloaded" } )

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

Ruby-код можно использовать Kernel#at_exit,

at_exit { puts "This code runs when Ruby exits." }

Реализация ядра #at_exit в eval_jump.c вызывает функцию C, rb_set_end_proc(), Эта функция общедоступна, поэтому вы можете вызывать ее из своего собственного C-кода. Декларация

void rb_set_end_proc(void (*)(VALUE), VALUE);

Первый аргумент - указатель на вашу функцию C (чтобы вызываться при выходе из Ruby). Вторым аргументом является значение Ruby для передачи в вашу функцию C.

Другие вопросы по тегам