I would like to use a list in C, that i got from R. I realise the question is very similar to this: Passing a data frame from-to R and C using .call(). However, I fail in storing it in a pointer "*target", from where i would further use it.
R:
.Call("processlist", list(c(1,2), c(1,3,2), c(1,5,4,4)))
and in C:
#include <Rinternals.h> #include <Rdefines.h> extern "C" { SEXP processlist(SEXP lst); } SEXP processlist(SEXP lst){ SEXP vec = PROTECT(allocVector(VECSXP, 2)); SET_VECTOR_ELT(vec, 0, VECTOR_ELT(c, 0); SET_VECTOR_ELT(vec, 1, VECTOR_ELT(c, 1); SET_VECTOR_ELT(vec, 2, VECTOR_ELT(c, 2); const lngth = 3; int *target[lnght]; // Here i want to fill "target", but how? int *preTarget = INTEGER(vec); // Bad attempts target[0] = INTEGER(preTarget[0]); target[0] = INTEGER(vec[0]); }
Note: C++ is not an Option unfortunately.
Edit: Desired output would be that I can call *target the following way.
target[0][0] --> Returns: 1 target[1][2] --> Returns: 2 target[2][3] --> Returns: 4
Calling "vec" in that way throws me an error at the moment.
1 Answers
Answers 1
It seems to me that you just want to access the values in the list from the C side. If that's correct, look at the code below.
In d.c
:
/* Including some headers to show the results*/ #include <Rinternals.h> #include <Rdefines.h> #include <R.h> #include <stdlib.h> #include <stdio.h> SEXP processlist(SEXP lst){ int i,l = length(lst); /* You need an array of arrays, so target will be an int** */ int **target = malloc(sizeof(int *)*l); for (i=0;i<l;i++) { target[i] = INTEGER(VECTOR_ELT(lst,i)); } printf("target[0][0]: %d\n",target[0][0]); printf("target[1][2]: %d\n",target[1][2]); printf("target[2][3]: %d\n",target[2][3]); free(target); return R_NilValue; }
The important thing to notice is that target
has to be an int**
, since it is a pointer to an array of pointers.
In d.R
(after d.c
has been compiled):
dyn.load("d.so") mylist<-list(c(1,2), c(1,3,2), c(1,5,4,4)) #This is very important: by default 1 in R is double. #You need to coerce every element of the list to integer. mylist<-lapply(mylist,as.integer) .Call("processlist", mylist)
Note that we need to coerce each element of the list to integer. The above produces:
target[0][0]: 1 target[1][2]: 2 target[2][3]: 4
0 comments:
Post a Comment