'unlockEnvironment' implementiert über 'Rcpp' anstelle von 'inline'
Kann mir jemand erklären, was ich tun muss, um den Code von @ zu implementiereunlockEnvironment
unten in Rcpp?
Kam über diesePos und versuchte Winston Chang's Lösung basierend auf C-Code mitin der Reih. Es funktioniert, aber ich habe das Gefühl, dass ich zu wenig (praktisch nichts) über Inline oder C / C ++ weiß, um wirklich zu wissen, was ich tue ;-)
So dachte ich, dies wäre eine großartige Gelegenheit, endlich zu lernen, wie man R als Schnittstelle zu C und C ++ verwendet. Und ich denke, ich würde gerne auf der @ ho Rcpp Zug dafür!
Der Code von WinstonKerrequire("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
)
Refactoring errorEine Randnotiz: Ich bin auf einen Fehler mit Winstons Code gestoßen, als ich ihn im @ auf eine bestimmte Weise organisiert/R
Verzeichnis meines Paketprojekts:
ch habe die meiste Zeit mit S4-Methoden versucht, Winstons Code in eine Standard-R-Funktion zu zerlege.unlockEnvironment()
dass ich in die Datei/R/.unlockEnvironment.r
Ich würde dann meine S4-Methoden für @ erstellunlockEnvironment()
im/R/unlockEnvironment.r
. Die Methode mit Signaturenv:environment
würde dann einfach @ anruf.unlockEnvironment(env = env)
.
Wenn ich die Dinge so einstelle, erhalte ich den folgenden Fehler:
Error in .Primitive (". Call") (, env): NULL-Wert als Symboladresse übergeben
Wenn ich den Code in @ einfü/R/.unlockEnvironment.r
Verzeichnis mit in der jeweiligen Methode in/R/unlockEnvironment.r
(so wird der Inline-Code jedes Mal neu bezogen, wenn die entsprechende Methode vonunlockEnvironment()
heißt), alles funktioniert einwandfrei - ist aber wegen des wiederholten Re-sourcings sehr ineffizient.
Also, ich denke, das muss entweder etwas mit der Art und Weise zu tun haben, wie der C-Code geschrieben ist, oder mit der Art und Weise, wie Sie Ihre C-basierten Funktionen organisieren müssen, wenn Sie @ verwendein der Reih?