Skip to content

Instantly share code, notes, and snippets.

@slwu89
Created June 26, 2018 00:59
Show Gist options
  • Save slwu89/e70af395e4578625f96788a78fda8e03 to your computer and use it in GitHub Desktop.
Save slwu89/e70af395e4578625f96788a78fda8e03 to your computer and use it in GitHub Desktop.
how to call multiple functions with parameters and ... in C using R's C API
/* evaluate 2 functions with ... (but must take same named args) */
SEXP C_example(SEXP call, SEXP rho){
SEXP args = CDR(call);
/* make up some 'arguments' for our two functions we want to call */
SEXP a1 = PROTECT(allocVector(REALSXP,1));
SEXP b1 = PROTECT(allocVector(REALSXP,1));
REAL(a1)[0] = 5.;
REAL(b1)[0] = 10.;
/* get the symbols to the functions */
SEXP afun = install("afun");
args = CDR(args);
SEXP bfun = install("bfun");
args = CDR(args);
/* make the function calls; note that both functions must take same args */
SEXP a1call = PROTECT(LCONS(afun, LCONS(a1, LCONS(R_DotsSymbol, R_NilValue))));
SEXP b1call = PROTECT(LCONS(bfun, LCONS(b1, LCONS(R_DotsSymbol, R_NilValue))));
/* evaluate */
SEXP aRes = R_forceAndCall(a1call, 1, rho);
SEXP bRes = R_forceAndCall(b1call, 1, rho);
SEXP out = PROTECT(allocVector(VECSXP,2));
SET_VECTOR_ELT(out,0,aRes);
SET_VECTOR_ELT(out,1,bRes);
UNPROTECT(5);
return out;
}
/* R wrapper using .Call */
#' test
#' @useDynLib mypackage C_rdiff
#' @export
test <- function(afun,bfun,...){
call <- match.call(expand.dots = FALSE)
.Call(C_example,call,environment())
}
afun <- function(x,y){return(x+10+y)}
bfun <- function(x,y){return(x+5)}
test(afun,bfun,y=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment