How to publish a constant string in Rust RFI?

I want the Rust library to map the old const char * string to C in order to be compatible with the existing interface (in particular librsync ). That is, the C header file has

 extern char const *my_string; 

In C, a library would just have

 char const *my_string = "hi"; 

In Rust, I tried something like

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

but it complains

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

It seems like I cannot use CString , etc., because they will not be a constant expression of compile time.

+5
source share
2 answers

It's a little weird, so bear with me ...

 #[repr(C)] pub struct StaticCString(*const u8); unsafe impl Sync for StaticCString {} #[no_mangle] pub static CONST_C_STR: StaticCString = StaticCString(b"a constant c string\0" as *const u8); 

Ideally, we could just have an open, static, odd, constant pointer to some bytes, right? However, you cannot do this because you will get this error:

 error: the trait `core::marker::Sync` is not implemented for the type `*const u8` [E0277] pub static CONST_C_STR: *const u8 = b"a constant c string\0" as *const u8; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

I did not spend much time understanding why this is so. It seems that an immutable pointer should not cause too many problems ...

However, we can tell the compiler that our type is safe to use in a multi-threaded environment. That's why there is a shell type - it allows us to implement Sync for the type that we have. A singleton structure should always have the same implementation as the wrapped value, but we continue and mark it as repr(C) to be safe.

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); } 
+5
source

The c_str_macro box provides a convenient c_str! macro c_str! which adds 0 bytes to the string string literal and represents it as a CStr .

Disclaimer: I am the author of the box.

+1
source

Source: https://habr.com/ru/post/1236529/


All Articles