rustffi

How to publish a constant string in the Rust FFI?


I want to have a Rust library expose a const char * static string to C, to be compatible with an existing interface (specifically librsync). That is, the C header file has

extern char const *my_string;

In C, the library would simply have

char const *my_string = "hi";

In Rust I've tried something like

pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char };

but this complains

error: casting `&'static str` as `*const i8` is invalid

It seems like I can't use CString etc because they won't be a compile-time constant expression.


Solution

  • We need a public, static, unmangled pointer to some zero-terminated bytes:

    #[export_name = "CONST_C_STR"] // or #[no_mangle]
    pub static CONST_C_STR: &[u8; 20] = b"a constant c string\0";
    

    This worked with a simple C program:

    #include <stdio.h>
    
    extern const char * const CONST_C_STR;
    
    int main(int argc, char *argv[]) {
      printf("%s\n", CONST_C_STR);
    }