# Calling C from R: The .Call() Interface Jan de Leeuw Version 001 08/04/2016 # Vector of Numbers ```c #include #include #include SEXP myHypot (SEXP x, SEXP y) { R_len_t nProtected = 0; SEXP z = PROTECT (allocVector (REALSXP, 1)); nProtected++; double *h = REAL (z); *h = hypot (REAL (x)[0], REAL (y)[0]); UNPROTECT (nProtected); return (z); } ``` ```r .Call("myHypot", as.double(3), as.double (4)) ``` ``` ## [1] 5 ``` ## NA ```c #include #include SEXP square (SEXP x) { R_len_t i, n = length (x), nProtected = 0; SEXP y = PROTECT (allocVector (REALSXP, n)); nProtected++; double *v = REAL (y), *z; if (TYPEOF (x) == REALSXP) { z = REAL (x); } else { z = REAL (coerceVector (x, REALSXP)); } for (i = 0; i < n; i++) { v[i] = R_NaInt == z[i] ? -1 : z[i] * z[i]; } UNPROTECT (nProtected); return (y); } ``` ```r .Call("square", as.double(c(1, NA, 2, "3", -1))) ``` ``` ## [1] 1 NA 4 9 1 ``` ```r .Call("square", as.double(c(1, NA, 2, "a", -1))) ``` ``` ## Warning: NAs introduced by coercion ``` ``` ## [1] 1 NA 4 NA 1 ``` ##Matrices and Arrays ###From R to C ###From C to R ##Attributes #Characters ##From R to C ##From C to R #Lists ##From R to C ##From C to R #Functions and Expressions ##Calling an R function from C ```c #include #include SEXP myRnorm (SEXP n) { R_len_t nProtected = 0, *m = INTEGER (n); SEXP y = PROTECT (allocVector (REALSXP, *m)); nProtected++; SEXP rnorm = install("rnorm"); y = eval (lang2 (rnorm, ScalarInteger(*m)), R_GlobalEnv); UNPROTECT (nProtected); return (y); } ``` ```r .Call("myRnorm", as.integer(5)) ``` ``` ## [1] 1.17301833 1.15044064 1.77913646 0.02589469 -0.16361843 ``` ```c #include #include SEXP myFirstN (SEXP n) { R_len_t nProtected = 0, *m = INTEGER (n); SEXP y = PROTECT (allocVector (REALSXP, *m)); nProtected++; SEXP firster = install("firstN"); y = eval (lang2 (firster, ScalarInteger(*m)), R_GlobalEnv); UNPROTECT (nProtected); return (y); } ``` ```r firstN <- function (n) 1:n .Call("myFirstN", as.integer(5)) ``` ``` ## [1] 1 2 3 4 5 ``` ##Passing R function to C # Vectors of Characters