Skip to content

Instantly share code, notes, and snippets.

@coolbutuseless
Created October 24, 2024 22:58
Show Gist options
  • Save coolbutuseless/a5c301da3c5f259c4cae1b0305d52a8f to your computer and use it in GitHub Desktop.
Save coolbutuseless/a5c301da3c5f259c4cae1b0305d52a8f to your computer and use it in GitHub Desktop.
Passing a function pointer through R
library(callme)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Code Segment 1
# 1. Define an 'adder()' function
# 2. Wrapper function to return the address of this function
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
code1 <- r"(
int adder(int x) {
return x + 1;
}
SEXP getter(void) {
return R_MakeExternalPtr(adder, R_NilValue, R_NilValue);
}
)"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Code Segment 2
# 1. Receive the function pointer as an argument
# 2. Call the function: adder(1) => 2
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
code2 <- r"(
SEXP fcaller(SEXP f_, SEXP val_) {
if (TYPEOF(f_) != EXTPTRSXP) error("Not an external pointer");
int (*fptr)(int);
fptr = R_ExternalPtrAddr(f_);
int res = (*fptr)(asInteger(val_));
return ScalarInteger(res);
}
)"
compile(code1)
compile(code2)
f <- getter()
fcaller(f, 99)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment