W poniższym kodzie tworzony jest obiekt typu foo z wywołaniem foo_new(), a zewnętrzny wskaźnik do obiektu jest zwracany do R Kolejne obliczenia są wykonywane przez przekazanie ptr_foo. Obiekt jest ostatecznie zwalniany przez jawne wywołanie foo_free (foo * X). Wszystkie obliczenia są wykonywane przez libfoo.Interfejs R .call() i EXTPTRSXP: Opis PROTECT/UNPROTECT z zewnętrznie przydzielonymi obiektami
Czy fakt, że ptr_foo zostało utworzone, oznacza, że wszystkie inne dynamicznie przydzielane pola w obiekcie foo są automatycznie chronione? Czy jest możliwe, że pola takie jak "bar" mogą zostać usunięte przez garbage collectora?
SEXP foo_new (SEXP n) {
SEXP ptr_foo;
foo *X = (foo*) foo_new(1, sizeof(foo));
//foo is protected from garbage collection
assert(X);
X->bar = (int*) foo_add_bar(INTEGER_VALUE(n));
//Is bar protected from garbage collection?
assert(X->bar);
PROTECT(ptr_foo = R_MakeExternalPtr(X, install("extptr_foo"), R_NilValue));
R_RegisterCFinalizerEx(ptr_foo, ptr_foo_finalize, 1);
UNPROTECT(1);
return (ptr_foo);
}
Dzięki
RT
Dzięki Tommy. Tego właśnie oczekiwałem. Jak wskazujesz, cała wymiana danych między R i libfoo odbywa się poprzez kopiowanie SEXP do i na zewnątrz. Wszystkie obiekty przydzielone przez bibliotekę są zwalniane przez wywołanie foo_free(). – user151410