On 12/16/2013 09:18 AM, Krzysztof Mlynarczyk wrote:
Yes, it turned out that using R_PreserveObject and R_ReleaseObject
solved that problem.
Instead I think you want to use the third argument to R_MakeExternalPtr to
protect the SEXP's you'd like to persist for the duration of the object, maybe
having bundled your ans, ans_nms, R_z, R_a, R_b, R_c into a list. This is
suggested by the argument name 'prot' and description in Writing R Extensions
section 5.13.
Martin
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
--
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109
Location: Arnold Building M1 B861
Phone: (206) 667-2793
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel