Yes, it turned out that using R_PreserveObject and R_ReleaseObject solved that problem. I sincerely apologize for posting only several chunks of code. Fortunately for me, the descritpion I gave was sufficient to track down what was missing. Thank you very much!
Chris 2013/12/16 Prof Brian Ripley <rip...@stats.ox.ac.uk>: > On 16/12/2013 11:07, Krzysztof Mlynarczyk wrote: >> >> As far as I understood the documentation, external pointer should be >> automatically protected from gc when returned to environment. The > > > Yes, but you didn't give us the complete reproducible example the posting > guide asks for. Peter's diagnosis is very likely right, but you have failed > to give us anything like enough to go on. > > >> solution you've just suggested would cause stack imbalance. > > > It would not work anyway: the pointer stack top is reset when .Call (or > similar) returns. > > There is R_PreserveObject for this purpose. > > >> 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 >> > > > -- > Brian D. Ripley, rip...@stats.ox.ac.uk > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel