Search code examples
crustffi

How can I access a C global variable/constant in Rust FFI?


I need to access a value of a constant exported from C in Rust.

I want to read the value from the actual symbol, and not just copy'n'paste the value to Rust (in my case the value is a pointer, and C checks for pointer equality).

extern void *magic;

What's the syntax to get magic: *const c_void readable in Rust?


Solution

  • use std::os::raw::c_void;
    
    extern "C" {
        static magic: *const c_void;
    }
    

    Optionally, before the extern there can be #[link(kind="static", name="<c library name>")] to get the symbol actually linked.

    Externally linkable items, even if constant, need be declared with static, not just const keyword (otherwise you get "extern items cannot be const").

    Important note: Rust does not allow static to be mutated, even from C, unless the Rust type is declared as Atomic* or other type with UnsafeCell. See https://github.com/rust-lang/unsafe-code-guidelines/issues/514.