How to create a named list (SEXP) that will be returned from a C function called with .Call ()?
I call the C code via .Call("foo", <args>) , where foo calls the other C functions, computes the result, and returns it. The result is a list of length 3, and I would call this list. To this end, foo does this:
/* Construct result list from variables containing the results */ SEXP res = PROTECT(allocVector(VECSXP, 3)); /* list of length 3 */ SET_VECTOR_ELT(res, 0, ScalarReal(a)); /* numeric(1) */ SET_VECTOR_ELT(res, 1, somenumericvector); /* numeric(<some length>) */ SET_VECTOR_ELT(res, 2, ScalarInteger(i)); /* integer(1) */ /* Name components and return */ SEXP nms = PROTECT(allocVector(STRSXP, 3)); /* names as SEXP */ char *nms_ = CHAR(STRING_ELT(nms, 0)); /* pointer to names */ char *names[3] = {"result_numeric", "result_numeric_vector", "result_integer"}; for(i = 0; i < 3; i++) nms_[i] = names[i]; setAttrib(res, R_NamesSymbol, nms); UNPROTECT(1); return res; Is this the correct rule for constructing a named list of length 3?
The C function does return to R, but as soon as I assign the output to a variable in R, I immediately get a segmentation error. What could be wrong? I can put a 'debugging instruction' (a simple printf("...\n") right before Res returns; "and they executed perfectly. Is there a convenient way to debug C code called from R?
An alternative to BrodieG's answer is to use mkNamed from Rinlinedfuns.h (which contains an example of using mkNamed ).
/* Construct named result list from variables containing the results */ const char *names[] = {"result_numeric", "result_numeric_vector", "result_integer", ""}; /* note the null string */ SEXP res = PROTECT(mkNamed(VECSXP, names)); /* list of length 3 */ SET_VECTOR_ELT(res, 0, ScalarReal(a)); /* numeric(1) */ SET_VECTOR_ELT(res, 1, somenumericvector); /* numeric(<some length>) */ SET_VECTOR_ELT(res, 2, ScalarInteger(i)); /* integer(1) */ UNPROTECT(1); return res; Since you are asking for a simple vanilla path, you need to create a character vector R from the C strings using mkChar and SET_STRING_ELT :
for(i = 0; i < 3; i++) SET_STRING_ELT(nms, i, mkChar(names[i])); You are currently trying to use a raw C string as an R object that will not work.
Re: debugging, you can use PrintValue in C code to output R objects.
All of this said, if you have no particular reason to want plain vanilla, you should consider Rcpp .
Per @nrussell good advice, single-expression solution (four-line break for readability)
R> cppFunction('List marius(double a, NumericVector b, int c) \ { return List::create(Named("resnum")=a,\ Named("resvec")=b, \ Named("resint")=c); }') R> marius(1.2, sqrt(3:5), 42L) $resnum [1] 1.2 $resvec [1] 1.73205 2.00000 2.23607 $resint [1] 42 R>