如何在Rust FFI中发布一个常量字符串?

7

我希望一个Rust库可以向C公开一个const char *类型的静态字符串,以便与现有接口(具体来说是librsync)兼容。也就是说,C头文件包含以下内容:

extern char const *my_string;

在C语言中,该库只需

char const *my_string = "hi";

在Rust中,我尝试了类似以下的代码:
pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char };

但是这个抱怨。
error: casting `&'static str` as `*const i8` is invalid

看起来我不能使用CString等,因为它们不是编译时常量表达式。

2个回答

9
我们需要一个公共的、静态的、未混淆的指针来引用一些以零结尾的字节:
#[export_name = "CONST_C_STR"] // or #[no_mangle]
pub static CONST_C_STR: &[u8; 20] = b"a constant c string\0";

这可以通过一个简单的C程序实现:

这可以通过一段简单的C语言程序来实现:

#include <stdio.h>

extern char * CONST_C_STR;

int main(int argc, char *argv[]) {
  printf("%s\n", CONST_C_STR);
}

谢谢!这正是我在寻找的,而且确实很奇怪。我打开了https://dev59.com/H5Hea4cB1Zd3GeqPomQE,想问为什么全局变量不是“同步”。 - poolie

2

这个箱子c_str_macro提供了一个方便的宏c_str!,它将0字节附加到Rust字符串文字并将其呈现为CStr引用。

免责声明:我是该板条箱的作者。


有趣的是,cstr! crate 大约在3年前发布。现在似乎更受欢迎了。我想知道,这是否只是一个下划线的差别呢? :) - ratijas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接