Created
June 26, 2018 00:59
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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