how to inhibit R garbage collection when passing objects to C/C++?
Having some trouble with R's garbage collection, when passing objects to C++.
We have the following scenario:
- we create an anonymous function in R, and pass it to C++ code (via .Call())
- the C++ code stores the R function object for later use (as a SEXP type) and returns
- later on, some other C++ code invokes said R function object using R_tryEval()
Between steps 2 and 3, the R function object appears to get garbage-collected by R. This leads to a crash because R_tryEval() tries to execute something that no longer represents a valid R function object. That's fair, as we haven't done anything to tell R that the function object is still in use...
With that in mind:
- is there a way, from the C++ code, to mark the R function object as being in-use (such that it doesn't get gc'd)?
- or is there a safe way to duplicate the R function object, within the C++ code, and manually dispose of it after we invoke R_tryEval()?
(As far as I understand, the PROTECT()/UNPROTECT() macros are not an option here because those are supposed to balance out within the same scope. As in, we can't call PROTECT() when the function is first passed to C++ and then later call UNPROTECT() after it has been executed.)
I think you're looking for
/* preserve objects across GCs */ void R_PreserveObject(SEXP); void R_ReleaseObject(SEXP);
in the R_internals.h header.