forked from tidyverse/dplyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrlang-export.c
37 lines (30 loc) · 1005 Bytes
/
rlang-export.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define R_NO_REMAP
#include <Rinternals.h>
#include <Rversion.h>
#include <tools/rlang-export.h>
#if (defined(R_VERSION) && R_VERSION < R_Version(3, 4, 0))
SEXP R_MakeExternalPtrFn(DL_FUNC p, SEXP tag, SEXP prot) {
fn_ptr ptr;
ptr.fn = p;
return R_MakeExternalPtr(ptr.p, tag, prot);
}
DL_FUNC R_ExternalPtrAddrFn(SEXP s) {
fn_ptr ptr;
ptr.p = EXTPTR_PTR(s);
return ptr.fn;
}
#endif
SEXP rlang_namespace(const char* ns) {
SEXP call = PROTECT(Rf_lang2(Rf_install("getNamespace"), PROTECT(Rf_mkString(ns))));
SEXP ns_env = Rf_eval(call, R_BaseEnv);
UNPROTECT(2);
return ns_env;
}
void rlang_register_pointer(const char* ns, const char* ptr_name, DL_FUNC fn) {
SEXP ptr = PROTECT(R_MakeExternalPtrFn(fn, R_NilValue, R_NilValue));
SEXP ptr_obj = PROTECT(Rf_allocVector(VECSXP, 1));
SET_VECTOR_ELT(ptr_obj, 0, ptr);
Rf_setAttrib(ptr_obj, R_ClassSymbol, Rf_mkString("fn_pointer"));
Rf_defineVar(Rf_install(ptr_name), ptr_obj, PROTECT(rlang_namespace(ns)));
UNPROTECT(3);
}