Hi, One solution to protect an object from the GC is to use the R_PreserveObject and R_ReleaseObject functions.
This way, you are not subject to the stack that PROTECT, UNPROTECT, UNPROTECT_PTR uses. Using R_PreserveObject and R_ReleaseObject is one of the best things that has ever happened to Rcpp. Romain Le 16 déc. 2013 à 12:07, Krzysztof Mlynarczyk <mitomas...@gmail.com> a écrit : > As far as I understood the documentation, external pointer should be > automatically protected from gc when returned to environment. The > solution you've just suggested would cause stack imbalance. > Recently I've been thinking of encapsulating the pointer into a nice > object using Rcpp. This sounds better that telling people to have fun > with an external pointer itself. > > KM > > 2013/12/16 peter dalgaard <pda...@gmail.com>: >> Offhand, I'd say that if "all protects get unprotected before return" >> mydata->ans is not protected against garbage collection, and thus very >> likely collected and reused. If mydata is created by Calloc, the GC has no >> way of knowing that it might have pointers to things that are intended to >> persist. >> >> I haven't played with external pointers for a while, but I'd expect that >> you'd need to retain a PROTECT on mydata->ans, and then UNPROTECT_PTR or so >> in the finalizer. >> >> -pd >> >> On 16 Dec 2013, at 04:11 , Krzysztof Mlynarczyk <mitomas...@gmail.com> wrote: >> >>> Dear Developers, >>> >>> >>> I've been struggling through writing R extension in C. I've been using >>> an external pointer to store my data (please see sample below). I >>> encountered a very weird erroneous behaviour: when I tried to use my >>> external pointer to a structure holding several types of data, >>> including SEXPs, I discovered that SEXPs change their types between >>> returning from initialization function and another one that uses the >>> pointer. >>> >>> sample R code: >>> >>> # initializing >>> a <- init_my_ptr(fname) >>> >>> # reading more data: error! >>> df <- read_my_data(a) >>> >>> data structure in C: >>> typedef struct { >>> SEXP ans, ans_nms, R_z, R_a, R_b, R_c; >>> FTYPE *datafile; >>> char *fname; >>> float *a, *b, *c; >>> int f_type; >>> float t, p, l; >>> int st, na, result, bFlags; >>> XXX z; >>> } my_data_ptr; >>> >>> // In a C function initializing the external pointer: >>> my_data_ptr *mydata = Calloc( 1, my_data_ptr ) ; >>> SEXP Rdata; >>> PROTECT(Rdata = R_MakeExternalPtr( mydata, R_fname, R_NilValue )); >>> ... >>> mydata->a = Calloc(mydata->na, float); >>> // same for b and c >>> // initializing names so that I could use e.g. df$a where df is >>> returned by read_my_data() >>> PROTECT(mydata->ans_nms = Rf_allocVector(STRSXP, efldNR )); >>> for( ix = 0; ix < efldNR; ix++ ) >>> SET_STRING_ELT(mydata->ans_nms, ix, mkChar(vnames[ix])); >>> >>> // later I bind values of non-R variables from my data structure to a >>> proper vector >>> PROTECT(mydata->ans = Rf_allocVector(VECSXP, efldNR )); >>> >>> Rf_setAttrib(mydata->ans, R_NamesSymbol, mytraj->ans_nms); >>> SET_VECTOR_ELT(mydata->ans, 0, mydata->R_a ); >>> SET_VECTOR_ELT(mydata->ans, 1, mydata->R_b ); >>> ... >>> // all protects get unprotected before return >>> // finalizer is registered as well >>> return Rdata; >>> >>> Later on in read_my_data() I read the pointer: >>> my_data_ptr *mydata = (my_data_ptr*) R_ExternalPtrAddr(Rdata); >>> >>> // and REAL(mydata->R_a) yields error since TYPEOF(mydata->R_a) is not >>> REALSXP as it should be but RAWSXP for some reason // (sometimes it's >>> STRSXP or INTSXP while it should always be REALSXP) >>> // The error message says: >>> // REAL() can only be applied to a 'numeric', not a 'raw' >>> >>> // mydata->ans is the object returned to R where all the data is made >>> available to R user: >>> return mydata->ans; >>> >>> // end of example code >>> >>> Could you please point the possible reasons for the error along with >>> the ways of fixing this issue? I've been trying in R-3.0.2, 3.0.1 and >>> even 2.15 -- the problem happens in each of them. >>> >>> >>> Regards, >>> Christopher >>> >>> ______________________________________________ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> -- >> Peter Dalgaard, Professor >> Center for Statistics, Copenhagen Business School >> Solbjerg Plads 3, 2000 Frederiksberg, Denmark >> Phone: (+45)38153501 >> Email: pd....@cbs.dk Priv: pda...@gmail.com >> > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel