callme compiles inline C code and generates wrappers so that the C code can be easily called from R.
Features:
- Compile inline C code (or code from a file) and makes it immediately (and easily!) available to R.
 - Accepts complete C code - including function declaration and header 
#includedirectives. - Explicit handling for 
CFLAGS,PKG_CPPFLAGSandPKG_LIBSfor setting compiler flags, C pre-processor flags, and library linking flags, respectively. - Generates R functions to call the compiled C functions.
 - Multiple function definitions allowed in a single code block.
 
What’s in the box
- 
compile(code, CFLAGS, PKG_CPPFLAGS, PKG_LIBS, env, verbosity)compile the Ccodeand assign R functions into the nominatedenvin R. C code could be as a string or in a file. - 
cflags_default()the default C compiler flags R uses on your system 
Installation
You can install from GitHub with:
# install.package('remotes')
remotes::install_github('coolbutuseless/callme')Example
The following example compiles a code snippet into a C library and creates a wrapper function in R (of the same name) which can be used to call the compiled code.
library(callme)
code <- "
#include <R.h>
#include <Rinternals.h>
// Add 2 numbers
SEXP add(SEXP val1, SEXP val2) {
  return ScalarReal(asReal(val1) + asReal(val2));
}
// Multiply 2 numbers
SEXP mul(SEXP val1, SEXP val2) {
  return ScalarReal(asReal(val1) * asReal(val2));
}
// sqrt elements in a vector
SEXP new_sqrt(SEXP vec) {
  SEXP res = PROTECT(allocVector(REALSXP, length(vec)));
  double *res_ptr = REAL(res);
  double *vec_ptr = REAL(vec);
  for (int i = 0; i < length(vec); i++) {
    res_ptr[i] = sqrt(vec_ptr[i]);
  }
  
  UNPROTECT(1);
  return res;
}
"
# compile the code
compile(code)
# Call the functions
add(99.5, 0.5)
mul(99.5, 0.5)
new_sqrt(c(1, 4, 25, 999))Linking against an installed library
In this example we want to get the version of the zstd library (which has already been installed on the computer), and return it as a character string.
We need to tell R when compiling the code:
- to look in the 
/opt/homebrew/includedirectory forzstd.h. - to look for the actual 
zstdlibrary in/opt/homebrew/lib. - to link to the 
zstdlibrary (-lzstd) 
Note: This code works for zstd installed via homebrew on macOS. Paths will be different for other operating systems.
code <- r"(
#include <R.h>
#include <Rinternals.h>
#include "zstd.h"
  
SEXP zstd_version() {
  return mkString(ZSTD_versionString());
}
)"
# Compile the code 
compile(code, 
       PKG_CPPFLAGS = "-I/opt/homebrew/include", 
       PKG_LIBS     = "-L/opt/homebrew/lib -lzstd")
# Call the function
zstd_version()References
- Hadley’s R internals.
 - Advanced R Book has a specfic chapter or R’s interface to C.
 - Ella Kay’s UserR2024 conference presentation: “C for R users”
 - Book: Deep R Programming
 - Davis Vaughan’s Now you C me
 - c3po
 - R Native API
 
R project official documentation
- Writing R extensions Section 5 System and foreign language interfaces
 - R internals
 
