Attribute Macro napi_h::module_init

source ·
#[module_init]
Expand description

Marks a function or static variable as a library/executable constructor. This uses OS-specific linker sections to call a specific function at load time.

Multiple startup functions/statics are supported, but the invocation order is not guaranteed.

§Examples

Print a startup message (using libc_print for safety):

use libc_print::std_name::println;

#[ctor]
fn foo() {
  println!("Hello, world!");
}

println!("main()");

Make changes to static variables:

static INITED: AtomicBool = AtomicBool::new(false);

#[ctor]
fn foo() {
  INITED.store(true, Ordering::SeqCst);
}

Initialize a HashMap at startup time:

#[ctor]
static STATIC_CTOR: HashMap<u32, String> = {
  let mut m = HashMap::new();
  for i in 0..100 {
    m.insert(i, format!("x*100={}", i*100));
  }
  m
};

§Details

The #[ctor] macro makes use of linker sections to ensure that a function is run at startup time.

The above example translates into the following Rust code (approximately):

 #[used]
 #[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".init_array")]
 #[cfg_attr(target_os = "freebsd", link_section = ".init_array")]
 #[cfg_attr(target_os = "netbsd", link_section = ".init_array")]
 #[cfg_attr(target_os = "openbsd", link_section = ".init_array")]
 #[cfg_attr(target_os = "illumos", link_section = ".init_array")]
 #[cfg_attr(any(target_os = "macos", target_os = "ios", target_os = "tvos"), link_section = "__DATA_CONST,__mod_init_func")]
 #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
 static FOO: extern fn() = {
   #[cfg_attr(any(target_os = "linux", target_os = "android"), link_section = ".text.startup")]
   extern fn foo() { /* ... */ };
   foo
 };