Skip to content

Commit

Permalink
Fix module registration. (#93)
Browse files Browse the repository at this point in the history
* set up registration forwarding

* forward routine registraton from C to Rust

* avoid reading Rinternals.h.

* fix up examples (somewhat)
  • Loading branch information
clauswilke committed Dec 28, 2020
1 parent 6f738b0 commit 62d0c15
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 53 deletions.
14 changes: 6 additions & 8 deletions extendr-api/examples/R/data/src/entrypoint.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// We need to forward routine registration from C to Rust
// to avoid the linker removing the static library.

void R_init_data_extendr(void *dll);

// Take the address of the wrap__hello stub function to avoid
// the linker removing the static library.
//
// This will be removed in future versions with the module macro.
void R_init_libdata();

void *__dummy = (void*)&R_init_libdata;

void R_init_data(void *dll) {
R_init_data_extendr(dll);
}

3 changes: 1 addition & 2 deletions extendr-api/examples/R/hello/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ Then in R:

> library(hello)
> hello()
hello
NULL
[1] "hello"
>
14 changes: 6 additions & 8 deletions extendr-api/examples/R/hello/src/entrypoint.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// We need to forward routine registration from C to Rust
// to avoid the linker removing the static library.

void R_init_hello_extendr(void *dll);

// Take the address of the wrap__hello stub function to avoid
// the linker removing the static library.
//
// This will be removed in future versions with the module macro.
void R_init_libhello();

void *__dummy = (void*)&R_init_libhello;

void R_init_hello(void *dll) {
R_init_hello_extendr(dll);
}

11 changes: 7 additions & 4 deletions extendr-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
// `cargo expand` extension.
//
// Invoking the #[extendr_module] macro generates an entrypoint for the
// library that will be called by R.
// library that will be called by R. Note that we add a postfix
// `_extendr` to the init function because we need to forward routine
// registration from C to Rust, and the C function will be called
// `R_init_hello()`.
//
// ```ignore
// #[no_mangle]
// #[allow(non_snake_case)]
// pub extern "C" fn R_init_hello(info: *mut extendr_api::DllInfo) {
// pub extern "C" fn R_init_hello_extendr(info: *mut extendr_api::DllInfo) {
// let mut call_methods = Vec::new();
// init__hello(info, &mut call_methods);
// unsafe { extendr_api::register_call_methods(info, call_methods.as_ref()) };
Expand Down Expand Up @@ -485,7 +488,7 @@ impl syn::parse::Parse for Module {
/// ```ignore
/// #[no_mangle]
/// #[allow(non_snake_case)]
/// pub extern "C" fn R_init_hello(info: *mut extendr_api::DllInfo) {
/// pub extern "C" fn R_init_hello_extendr(info: *mut extendr_api::DllInfo) {
/// let mut call_methods = Vec::new();
/// init__hello(info, &mut call_methods);
/// unsafe { extendr_api::register_call_methods(info, call_methods.as_ref()) };
Expand All @@ -496,7 +499,7 @@ pub fn extendr_module(item: TokenStream) -> TokenStream {
let module = parse_macro_input!(item as Module);
let Module {modname, fnnames, implnames} = module;
let modname = modname.unwrap();
let module_init_name = format_ident!("R_init_{}", modname);
let module_init_name = format_ident!("R_init_{}_extendr", modname);

let fninitnames = fnnames.iter().map(|id| format_ident!("{}{}", INIT_PREFIX, id));
let implinitnames = implnames.iter().map(|id| format_ident!("{}{}", INIT_PREFIX, id));
Expand Down
31 changes: 5 additions & 26 deletions tests/extendrtests/src/entrypoint.c
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
/*
// Take the address of the wrap__hello stub function to avoid
// the linker removing the static library.
//
// This will be removed in future versions with the module macro.
void wrap__hello();
// We need to forward routine registration from C to Rust
// to avoid the linker removing the static library.

void *x = (void*)&wrap__hello;
*/
void R_init_extendrtests_extendr(void *dll);


#define R_NO_REMAP
#define STRICT_R_HEADERS
#include <Rinternals.h>

SEXP wrap__hello();
SEXP wrap__add_ints();

// Standard R package stuff
static const R_CallMethodDef CallEntries[] = {
{"wrap__hello", (DL_FUNC) &wrap__hello, 0},
{"wrap__add_ints", (DL_FUNC) &wrap__add_ints, 2},
{NULL, NULL, 0}
};

void R_init_extendrtests(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
void R_init_extendrtests(void *dll) {
R_init_extendrtests_extendr(dll);
}
6 changes: 3 additions & 3 deletions tests/extendrtests/src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ crate-type = ["staticlib"]
extendr-api = "*"

[patch.crates-io]
extendr-api = { git = "https://github.com/extendr/extendr" }
extendr-engine = { git = "https://github.com/extendr/extendr" }
extendr-macros = { git = "https://github.com/extendr/extendr" }
extendr-api = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" }
extendr-engine = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" }
extendr-macros = { git = "https://github.com/clauswilke/extendr", branch = "reg-forwarding" }
#libR-sys = { git = "https://github.com/extendr/libR-sys" }
3 changes: 1 addition & 2 deletions tests/extendrtests/src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ fn add_ints(x:i32, y:i32) -> i32 {
}


/* Doesn't currently work yet.
// Macro to generate exports
extendr_module! {
mod extendrtests;
fn hello;
fn add_ints;
}
*/

0 comments on commit 62d0c15

Please sign in to comment.