[R] allocating memory in C, not in R

Sundar Dorai-Raj sundar.dorai-raj at PDF.COM
Fri Sep 3 17:55:02 CEST 2004


Sigal Blay wrote:

> Thanks Sundar - but how do I return several vector objects of 
> different modes wrapped in a list object using .Call?
> 
> Sigal
> 


Have you looked at the documentation as I suggested? It's there in 
Section 4.8 of "Writing R Extensions". Take a look at the examples for 
"lapply" or look at Rdefines.h and Rinternals.h in the src/include 
directory.

You're lucky I have an already worked example I have used for myself in 
the past which I include below.

/* junk.c */
#include <R.h>
#include <Rdefines.h>

SEXP junk(SEXP n) {
   SEXP *p_b, *p_nm;
   SEXP val, a, b, c, val_nm;
   double *p_a;
   int *p_c;
   int i, len, val_len;
   char *nm[3] = {"numeric", "character", "integer"};
   char *LETTERS[26] = {"A", "B", "C", "D", "E", "F",
                        "G", "H", "I", "J", "K", "L",
                        "M", "N", "O", "P", "Q", "R",
                        "S", "T", "U", "V", "W", "X",
                        "Y", "Z"};
   val_len = 3;
   len = INTEGER_VALUE(n);
   PROTECT(val = allocVector(VECSXP, val_len));
   PROTECT(a = NEW_NUMERIC(len));
   PROTECT(b = NEW_CHARACTER(len));
   PROTECT(c = NEW_INTEGER(len));
   PROTECT(val_nm = NEW_CHARACTER(val_len));
   p_a = NUMERIC_POINTER(a);
   p_b = CHARACTER_POINTER(b);
   p_c = INTEGER_POINTER(c);
   p_nm = CHARACTER_POINTER(val_nm);
   for(i = 0; i < len; i++) {
     p_a[i] = 1/(double)(i + 1);
     p_b[i] = mkChar(LETTERS[i % 26]);
     p_c[i] = i + 1;
   }
   for(i = 0; i < val_len; i++)
     p_nm[i] = mkChar(nm[i]);
   SET_VECTOR_ELT(val, 0, a);
   SET_VECTOR_ELT(val, 1, b);
   SET_VECTOR_ELT(val, 2, c);
   setAttrib(val, R_NamesSymbol, val_nm);
   UNPROTECT(5);
   return val;
}

/* ## in R                                  */
/* dyn.load("junk")                         */
/* junk <- function(n = 1) .Call("junk", n) */
/* junk(4)                                  */


--sundar




More information about the R-help mailing list