#include #include static void cooked_goose(SEXP foo) { if (TYPEOF(foo) != EXTPTRSXP) error("argument not external pointer"); double *x = (double *) R_ExternalPtrAddr(foo); int blather = x[0]; Free(x); if (blather) printf("finalizer ran\n"); } SEXP blob(SEXP nin, SEXP blatherin) { if (! isInteger(nin)) error("n not integer"); int n = INTEGER(nin)[0]; if (! (n > 0)) error("n not positive"); if (! isLogical(blatherin)) error("blather not logical"); int blather = LOGICAL(blatherin)[0]; double *x = Calloc(n + 2, double); GetRNGstate(); for (int i = 0; i < n; ++i) x[i + 2] = norm_rand(); PutRNGstate(); x[1] = n; x[0] = blather; SEXP bar; PROTECT(bar = R_MakeExternalPtr(x, R_NilValue, R_NilValue)); R_RegisterCFinalizer(bar, cooked_goose); UNPROTECT(1); return bar; } SEXP blub(SEXP foo) { if (TYPEOF(foo) != EXTPTRSXP) error("argument not external pointer"); double *x = (double *) R_ExternalPtrAddr(foo); int blather = x[0]; int n = x[1]; SEXP bar; PROTECT(bar = allocVector(REALSXP, n)); for (int i = 0; i < n; ++i) REAL(bar)[i] = x[i + 2]; UNPROTECT(1); return bar; }