How to create a global variable visible by an FFI

The FFI - The Rustonomicon indicates how we can access a foreign global in Rust, but not how we might expose a global variable TO the FFI. I'm building against an SDK that has some C code in it that you'd normally build in that I'm trying to avoid if possible. That C code defines both a global variable and a function that initializes it. Creating the function is no problem, but I don't know how to create the global, so I'm getting linking errors.

I realize that I could compile the C code into a library and link that, but I'm wondering if I can avoid this extra step. I also realize that this is highly unsafe, a mutable global variable.. but the scenario I need this for is a unit testing framework so I'm not overly concerned (and know now to property set it up to be safe as I have the source code to the C side of things).

You can use the #[no_mangle] attribute to export a static with a non-mangled name, and #[used] to ensure it is not optimized out (even if no Rust code uses it within the current crate):

#[no_mangle]
#[used]
pub static mut MY_STATIC: u8 = 0;
1 Like

I'm getting an error: error: visibility pub is not followed by an item, if i remove pub i get errors about #[no_mangle]

An additional complication is that the pointer is to a struct defined by the FFI (exposed via a -sys library) which isn't not Sync, that I've authored the -sys crate so I could alter that.

ahh. pub static mut builds for MY_STATIC in this scenario, the order was just wrong..

BTW, this is what I ended up with, it resolves my issues:

#[no_mangle]
#[used]
pub static mut _common_symbols: *mut max_sys::t_common_symbols_table = std::ptr::null_mut();

thanks @mbrubeck

Oops! Fixed.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.