Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to publish a constant string in the Rust FFI?

Tags:

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.

like image 398
poolie Avatar asked Nov 22 '15 00:11

poolie


2 Answers

The crate c_str_macro provides a convenience macro c_str!, which appends a 0 byte to a Rust string literal and presents it as a CStr reference.

Disclaimer: I'm the author of the crate.

like image 28
mzabaluev Avatar answered Sep 18 '22 12:09

mzabaluev


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 char * CONST_C_STR;

int main(int argc, char *argv[]) {
  printf("%s\n", CONST_C_STR);
}
like image 151
Shepmaster Avatar answered Sep 19 '22 12:09

Shepmaster