'unlockEnvironment' implementado a través de 'Rcpp' en lugar de 'en línea'
¿Podría alguien ayudarme a comenzar lo que necesito hacer para implementar el código deunlockEnvironment
abajo enRcpp?
Encontré estoenviar y probé la solución de Winston Chang basada en el código C conen línea. Funciona, pero tengo la sensación de que sé muy poco (prácticamente nada, eso es) sobre Inline o C / C ++ para saber realmente lo que estoy haciendo ;-)
Así que pensé que esta sería una gran oportunidad para finalmente comenzar a aprender sobre cómo usar R como interfaz para C y C ++. Y creo que me gustaría subirme alRcpp entrenar para hacerlo!
El código de Winston'sEsenciarequire("inline")
inc <- '
/* This is taken from envir.c in the R 2.15.1 source
https://github.com/SurajGupta/r-source/blob/master/src/main/envir.c
*/
#define FRAME_LOCK_MASK (1<<14)
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
'
src <- '
if (TYPEOF(env) == NILSXP)
error("use of NULL environment is defunct");
if (TYPEOF(env) != ENVSXP)
error("not an environment");
UNLOCK_FRAME(env);
// Return TRUE if unlocked; FALSE otherwise
SEXP result = PROTECT( Rf_allocVector(LGLSXP, 1) );
LOGICAL(result)[0] = FRAME_IS_LOCKED(env) == 0;
UNPROTECT(1);
return result;
'
unlockEnvironment <- inline::cfunction(
signature(env = "environment"),
includes = inc,
body = src
)
Error de refactorizaciónEn una nota al margen: me encontré con un error con el código de Winston cuando lo organizo de cierta manera en el/R
directorio de mi proyecto de paquete:
Usando métodos S4 la mayor parte del tiempo, traté de factorizar el código de Winston en una función R estándar.unlockEnvironment()
que puse en el archivo/R/.unlockEnvironment.r
Luego crearía mis métodos S4 paraunlockEnvironment()
en/R/unlockEnvironment.r
. El método con firmaenv:environment
entonces simplemente llamaría.unlockEnvironment(env = env)
.
Configurando las cosas de esa manera, termino con el siguiente error:
Error en .Primitive (". Call") (, env): valor NULL pasado como dirección de símbolo
Si pongo el código en/R/.unlockEnvironment.r
directorio con en el método respectivo en/R/unlockEnvironment.r
(por lo tanto, volver a obtener el código en línea cada vez que el método respectivo deunlockEnvironment()
se llama), todo funciona bien, pero es muy ineficiente debido a la repetición de recursos.
Así que supongo que esto debe tener algo que ver con la forma en que se escribe el código C o con la forma en que necesita organizar sus funciones basadas en C cuando usaen línea?