2012-06-15 9 views
11

Masz problemy z usuwaniem śmieci R. Podczas przekazywania obiektów do C++.jak powstrzymać R garbage collection podczas przekazywania obiektów do C/C++?

Mamy następujący scenariusz:

  1. tworzymy anonimową funkcję w badania i przekazać go do kodu C++ (przez .Call())
  2. C kod ++ przechowuje obiekt funkcji R do późniejszego wykorzystania (jako SEXP typu) i zwraca
  3. później, inny kod C++ wywołuje wspomniany R funkcja obiektu przy R_tryEval()

pomiędzy etapami 2 i 3, obiekt funkcji R wydaje się zbierać śmieci przez R. Powoduje to awarię, ponieważ R_tryEval() próbuje wykonać coś, co nie reprezentuje już prawidłowego obiektu funkcji R. To sprawiedliwe, bo nie mają nic do powiedzenia, że ​​obiekt R funkcja jest nadal w użyciu zrobić ...

Mając to na uwadze:

  • czy istnieje sposób, z kodu C++, aby oznaczyć obiekt funkcji R jako będący w użyciu (taki, że nie zostanie pobrany gcd)?
  • lub czy istnieje bezpieczny sposób na skopiowanie obiektu funkcji R, w ramach kodu C++, i ręczne pozbycie się go po wywołaniu R_tryEval()?

(O ile mi zrozumieć, makra PROTECT()/UNPROTECT() nie są możliwe tutaj, bo te mają zrównoważyć w takim samym zakresie. Jak w, nie możemy nazwać PROTECT() gdy funkcja jest najpierw przekazywana do C++, a potem zadzwonić UNPROTECT() po jego wykonaniu.)

+0

W jaki sposób przechowujesz obiekt? Pomyślałbym (bez myślenia), że możesz użyć zewnętrznego wskaźnika. Jeśli nie, możesz po prostu utrzymać go przy życiu w R i użyć findVar, aby przywołać go w razie potrzeby. –

+0

@Jeff - dzięki. To, co opisałeś, jest bardzo bliskie rozwiązaniu, które wymyśliliśmy: dodając obiekty funkcji do listy, po stronie R, przed przekazaniem ich do C++. (Przy okazji, z radością to robimy ... chciałem tylko upewnić się, że nie ma "oficjalnej" funkcji, którą powinniśmy wywołać, aby oznaczyć obiekt jako nie-gc.) – qethanm

+1

Jeśli chodzi o hacki idź, to może zabrać ciasto. Zobacz odpowiedź Martina dla właściwego rozwiązania, nawet jeśli nie używasz Rcpp. –

Odpowiedz

3

myślę szukasz

/* preserve objects across GCs */ 
void R_PreserveObject(SEXP); 
void R_ReleaseObject(SEXP); 

w nagłówku R_internals.h.

+0

... a jeśli używałeś Rcpp, byłby on stosowany automagicznie do twoich obiektów. –

+0

Wielkie dzięki - to było to, po co byłem. Sprawa zamknięta. – qethanm

Powiązane problemy