The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Calling an R function from C involves:
SET_TAG()
eval()
Creating the special list for the call can be done using the helper
methods lang1()
to lang6()
, or for R 4.4.1 or
later allocLang()
can provide more flexibility if
needed.
lang1()
- Calling an R function with no argumentslang1()
is for assembling a call to an R function
without specifying any arguments.
In this example getwd()
is called from C using
lang1()
#include <R.h>
#include <Rinternals.h>
SEXP call_r_from_c_with_lang1(void) {
SEXP my_call = PROTECT(lang1(
PROTECT(Rf_install("getwd"))
));
SEXP my_result = PROTECT(eval(my_call, R_GlobalEnv));
UNPROTECT(3);
return my_result;
}
lang2()
- Calling an R function with a single unnamed
argumentlang2()
is for assembling a call to an R function and
specifying a single argument.
In this example abs(-1)
is called from C using
lang2()
#include <R.h>
#include <Rinternals.h>
SEXP call_r_from_c_with_lang2(void) {
SEXP val = PROTECT(ScalarReal(-1));
SEXP my_call = PROTECT(lang2(
PROTECT(Rf_install("abs")),
val
));
SEXP my_result = PROTECT(eval(my_call, R_GlobalEnv));
UNPROTECT(4);
return my_result;
}
code = r"(
#include <R.h>
#include <Rinternals.h>
SEXP call_r_from_c_with_lang2(void) {
SEXP val = PROTECT(ScalarReal(-1));
SEXP my_call = PROTECT(lang2(
PROTECT(Rf_install("abs")),
val
));
SEXP my_result = PROTECT(eval(my_call, R_GlobalEnv));
UNPROTECT(4);
return my_result;
}
)"
callme::compile(code)
lang2()
- Calling an R function with a single named
argumentIn this example tempfile(fileext = ".txt")
is called
from C using lang2()
#include <R.h>
#include <Rinternals.h>
SEXP call_r_from_c_with_lang2_named(void) {
// Assemble the function + argument with name
SEXP val = PROTECT(mkString(".txt"));
SEXP my_call = PROTECT(lang2(
PROTECT(Rf_install("tempfile")),
val
));
// Set the argument name
SEXP t = CDR(my_call);
SET_TAG(t, Rf_install("fileext"));
// Evaluate the call
SEXP my_result = PROTECT(eval(my_call, R_GlobalEnv));
UNPROTECT(4);
return my_result;
}
code = r"(
#include <R.h>
#include <Rinternals.h>
SEXP call_r_from_c_with_lang2_named(void) {
// Assemble the function + argument with name
SEXP val = PROTECT(mkString(".txt"));
SEXP my_call = PROTECT(lang2(
PROTECT(Rf_install("tempfile")),
val
));
// Set the argument name
SEXP t = CDR(my_call);
SET_TAG(t, Rf_install("fileext"));
// Evaluate the call
SEXP my_result = PROTECT(eval(my_call, R_GlobalEnv));
UNPROTECT(4);
return my_result;
}
)"
callme::compile(code)
allocLang()
(R >= 4.4.1 only)The C code is equivalent to this R code:
#include <R.h>
#include <Rinternals.h>
SEXP call_print_from_c(SEXP value, SEXP digits) {
// Allocate a new call object
SEXP my_call = PROTECT(allocLang(3));
// Manipulate a pointer to this call object to
// fill in the arguments and set argument names
SEXP t = my_call;
SETCAR(t, install("print")); t = CDR(t);
SETCAR(t, value) ; t = CDR(t);
SETCAR(t, digits);
SET_TAG(t, install("digits"));
eval(my_call, R_GlobalEnv);
UNPROTECT(1);
return R_NilValue;
}
code = r"(
#include <R.h>
#include <Rinternals.h>
SEXP call_print_from_c(SEXP value, SEXP digits) {
// Allocate a new call object
SEXP my_call = PROTECT(allocLang(3));
// Manipulate a pointer to this call object to
// fill in the arguments and set argument names
SEXP t = my_call;
SETCAR(t, install("print")); t = CDR(t);
SETCAR(t, value) ; t = CDR(t);
SETCAR(t, digits);
SET_TAG(t, install("digits"));
eval(my_call, R_GlobalEnv);
UNPROTECT(1);
return R_NilValue;
}
)"
callme::compile(code)
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.