'unlockEnvironment' implementiert über 'Rcpp' anstelle von 'inline'

Aktuelle Frage

Kann mir jemand erklären, was ich tun muss, um den Code von @ zu implementiereunlockEnvironment unten in Rcpp?

Hintergrun

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 WinstonKer
require("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 error

Eine 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?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage