Initialization Routine
#[savvy_init]
is a special version of #[savvy]
. The function marked with
this macro is called when the package is loaded, which is what Writing R
Extension calls "initialization routine". The function must take *mut DllInfo
as its argument.
For example, if you write such a Rust function like this,
use savvy::ffi::DllInfo;
#[savvy_init]
fn init_foo(_dll_info: *mut DllInfo) -> savvy::Result<()> {
r_eprintln!("Initialized!");
Ok(())
}
You'll see the following message on your R session when you load the package.
library(yourPackage)
#> Initialized!
Under the hood, savvy-cli update .
inserts the following line in a C function
R_init_*()
, which is called when the DLL is loaded.
void R_init_yourPackage(DllInfo *dll) {
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
R_useDynamicSymbols(dll, FALSE);
savvy_init_foo__impl(dll); // added!
}
This is useful for initializing resources. For example, you can initialize a global variable.
use std::sync::OnceLock;
static GLOBAL_FOO: OnceLock<Foo> = OnceLock::new();
#[savvy_init]
fn init_global_foo(dll_info: *mut DllInfo) -> savvy::Result<()> {
GLOBAL_FOO.get_or_init(|| Foo::new());
Ok(())
}
You can also register an ALTREP class using this mechanism see the next page.