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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With