Tiene problemas con la recolección de elementos no utilizados de R, al pasar objetos a C++.cómo inhibir la recolección de basura R al pasar objetos a C/C++?
tenemos el siguiente escenario:
- creamos una función anónima en R, y pasarlo a código C++ (a través de
.Call()
) - el código C++ almacena el objeto función R para su uso posterior (como se un tipo
SEXP
) y devuelve - más adelante, algún otro código C++ invoca dicho objeto función R usando
R_tryEval()
Entre los pasos 2 y 3, el objeto de la función R aparece para obtener el recolector de basura por R. Esto provoca un bloqueo porque R_tryEval()
intenta ejecutar algo que ya no representa un objeto de función R válido. Eso es justo, ya que no hemos hecho nada para contar R que el objeto función está todavía en uso ...
Con esto en mente:
- hay una manera, a partir del código C++, a marcar el objeto de la función R como en uso (de modo que no se obtenga gc'd)?
- o existe una forma segura de duplicar el objeto de la función R, dentro del código C++, y deshacerse de él manualmente después de invocar
R_tryEval()
?
(Por lo que yo entiendo, los PROTECT()
/UNPROTECT()
macros no son una opción aquí porque aquellos se supone que equilibrar dentro del mismo ámbito. Como en, no podemos llamar PROTECT()
cuando la función se pasa primero a C++ y luego llamar UNPROTECT()
después de que haya sido ejecutado.)
¿Cómo está 'almacenando' el objeto? Yo pensaría (sin pensar realmente) que puedes emplear un puntero externo. De lo contrario, quizás puedas simplemente mantenerlo vivo en R en alguna parte y usar findVar para recuperarlo cuando sea necesario. –
@Jeff - gracias. Lo que ha descrito está muy cerca de la solución que ideamos: agregar los objetos de función a una lista, en el lado R, antes de pasarlos a C++. (Por cierto, estamos contentos de seguir haciendo esto ... solo queríamos asegurarnos de que no hay una función "oficial" a la que se suponga que llamemos para marcar el objeto como do-not-gc). – qethanm
En cuanto a hacks ve, esto puede tomar el pastel. Consulte la respuesta de Martin para una solución adecuada, incluso si no utiliza Rcpp. –