Last active
May 6, 2019 00:28
-
-
Save lachlansneff/7306b2dea897a850092abbae569551ab to your computer and use it in GitHub Desktop.
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
pub trait Module { | |
fn id(&self) -> usize; | |
} | |
macro_rules! register { | |
($( $vis:vis static $name:ident: $t:ty = $e:expr; )*) => { | |
$( | |
#[used] | |
$vis static $name: $t = { | |
#[used] | |
#[link_section = "registered_inits"] | |
static PTR: &'static (dyn Module + Sync) = &$name; | |
$e | |
}; | |
)* | |
} | |
} | |
#[allow(improper_ctypes)] | |
extern "C" { | |
static __start_registered_inits: &'static dyn Module; | |
static __stop_registered_inits: &'static dyn Module; | |
} | |
pub fn modules() -> &'static [&'static dyn Module] { | |
unsafe { | |
let start: *const _ = &__start_registered_inits; | |
let end: *const _ = &__stop_registered_inits; | |
std::slice::from_raw_parts( | |
start, | |
(end as usize - start as usize) / std::mem::size_of::<&dyn Module>(), | |
) | |
} | |
} | |
pub struct Foo { | |
id: usize, | |
} | |
impl Module for Foo { | |
fn id(&self) -> usize { | |
self.id | |
} | |
} | |
struct Bar { | |
id: usize, | |
} | |
impl Module for Bar { | |
fn id(&self) -> usize { | |
self.id | |
} | |
} | |
register! { | |
pub static FOO_MODULE: Foo = Foo { id: 0 }; | |
static FOO_MODULE2: Foo = Foo { id: 1 }; | |
static FOO_MODULE3: Foo = Foo { id: 2 }; | |
static BAR_MODULE: Bar = Bar { id: 3 }; | |
} | |
fn main() { | |
println!("len: {}", modules().len()); | |
for module in modules() { | |
println!("id: {}", module.id()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment