Closed asomers closed 5 years ago
Hi @asomers :wave:
An unsafe variant of lazy_static
is probably out-of-scope for this library, but you can use Rust's own unsafe mutable static feature to provide a global mutable structure:
struct Pointers {
a: *mut u8,
b: *mut u8,
}
impl Pointers {
const UNINIT: Self = Pointers {
a: std::ptr::null_mut(),
b: std::ptr::null_mut(),
};
}
static mut POINTERS: Pointers = Pointers::UNINIT;
fn main() {
// Working with 'static mut is unsafe
// You're responsible for ensuring the mutable state is
// only aliased and accessed correctly
unsafe {
let pointers = &mut POINTERS;
// Pass through FFI
}
}
That helps! It makes it possible, but not easy, to do what I want. Using that technique, I can't initialize the variable with non-const
functions like mem::zeroed()
or mem::uninitialized()
. That's why I was hoping there would be a way to do it with lazy_static. Do you know of any way to initialize non-Sync
static variables with mem::zeroed()
?
Ok, I found a great hack. I can run code in a constructor function as soon as my library gets loaded, before the application can access it with dlsym
.
#[export_name = "mysymbol"]
pub static mut MYSYMBOL: Option<Foo> = None;
#[link_section = ".init_array"]
pub static INITIALIZE: extern "C" fn() = rust_ctor;
#[no_mangle]
pub extern "C" fn rust_ctor() {
unsafe {
MYSYMBOL = Some(Foo::new())
}
}
Thanks for the help. I'm going to close the issue now.
Ok, I found a great hack. I can run code in a constructor function as soon as my library gets loaded, before the application can access it with
dlsym
.#[export_name = "mysymbol"] pub static mut MYSYMBOL: Option<Foo> = None; #[link_section = ".init_array"] pub static INITIALIZE: extern "C" fn() = rust_ctor; #[no_mangle] pub extern "C" fn rust_ctor() { unsafe { MYSYMBOL = Some(Foo::new()) } }
Thanks for the help. I'm going to close the issue now.
Thank you for this; this really saved me from a multi-day bind. Still, why not just use a mutex around your global mutable var and ditch the unsafe keyword when accessing it?
would it be possible to create an
unsafe
version of the macro that allows the type to be non-Sync
? I would like to use it in an FFI context. The calling C code requires me to provide a global mutable structure containing raw pointers.