'unlockEnvironment' implementado via 'Rcpp' em vez de 'inline'
Alguém poderia me iniciar sobre o que preciso fazer para implementar o código deunlockEnvironment
abaixo emRcpp?
Deparei com issopostar e tentei a solução de Winston Chang baseada no código C comna linha. Funciona, mas tenho a sensação de que sei muito pouco (praticamente nada) sobre o inline ou o C / C ++ para realmente saber o que estou fazendo ;-)
Por isso, achei que seria uma ótima oportunidade para finalmente começar a aprender como usar o R como uma interface para C e C ++. E eu acho que gostaria de pular noRcpp treinar para fazê-lo!
O código do WinstonEssênciarequire("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
)
Erro de refatoraçãoEm uma nota lateral: encontrei um erro no código de Winston ao organizá-lo de uma certa maneira no/R
diretório do meu projeto de pacote:
Usando métodos S4 na maioria das vezes, tentei levar o código de Winston para uma função R padrão.unlockEnvironment()
que eu coloquei no arquivo/R/.unlockEnvironment.r
Eu então criaria meus métodos S4 paraunlockEnvironment()
no/R/unlockEnvironment.r
. O método com assinaturaenv:environment
simplesmente chamaria.unlockEnvironment(env = env)
.
Configurando as coisas dessa maneira, acabo com o seguinte erro:
Erro em .Primitive (". Call") (, env): valor NULL passado como endereço do símbolo
Se eu colocar o código em/R/.unlockEnvironment.r
diretório com no respectivo método em/R/unlockEnvironment.r
(reutilizando assim o código embutido sempre que o respectivo método deunlockEnvironment()
é chamado), tudo funciona muito bem - mas é muito ineficiente por causa do re-fornecimento repetido.
Portanto, acho que isso deve ter algo a ver com a maneira como o código C é escrito ou com a maneira como você precisa organizar suas funções baseadas em C ao usarna linha?