Как запретить сборку мусора R при передаче объектов на C/С++?

У некоторых проблем с сборкой мусора R при передаче объектов на С++.

Мы имеем следующий сценарий:

  • мы создаем анонимную функцию в R и передаем ее в код С++ (через .Call())
  • код С++ хранит объект функции R для последующего использования (как тип SEXP) и возвращает
  • позже, другой код С++ вызывает указанный объект функции R, используя R_tryEval()

Между этапами 2 и 3, объект функции R появляется, чтобы получить сбор мусора с помощью R. Это приводит к сбою, потому что R_tryEval() пытается выполнить то, что больше не представляет собой действительный объект функции R. Это справедливо, поскольку мы ничего не сделали, чтобы сказать R, что объект функции все еще используется...

Имея это в виду:

  • Есть ли способ из кода на С++ пометить объект функции R как используемый (такой, что он не получает gc'd)?
  • или существует безопасный способ дублирования объекта функции R в коде С++ и вручную утилизировать его после вызова R_tryEval()?

(Насколько я понимаю, макросы PROTECT()/UNPROTECT() здесь не являются опцией, поскольку они должны балансировать в пределах одной области действия. Как и в случае, мы не можем вызывать PROTECT(), когда функция сначала передается на С++, а затем вызывает UNPROTECT() после того, как он был выполнен.)

Ответ 1

Я думаю, что вы ищете

/* preserve objects across GCs */
void R_PreserveObject(SEXP);
void R_ReleaseObject(SEXP);

в заголовке R_internals.h.