Skip to content

Instantly share code, notes, and snippets.

@lachlansneff
Last active May 6, 2019 00:28
Show Gist options
  • Save lachlansneff/7306b2dea897a850092abbae569551ab to your computer and use it in GitHub Desktop.
Save lachlansneff/7306b2dea897a850092abbae569551ab to your computer and use it in GitHub Desktop.
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