Created
October 24, 2024 22:58
-
-
Save coolbutuseless/a5c301da3c5f259c4cae1b0305d52a8f to your computer and use it in GitHub Desktop.
Passing a function pointer through R
This file contains 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
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