[Rd] External pointers and changing SEXPTYPE
Krzysztof Mlynarczyk
mitomaster at gmail.com
Mon Dec 16 04:11:08 CET 2013
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
More information about the R-devel
mailing list