我想让Rust库const char *
向C 公开一个静态字符串,以便与现有接口(特别是librsync)兼容.也就是说,C头文件有
extern char const *my_string;
Run Code Online (Sandbox Code Playgroud)
在C中,图书馆就是这样
char const *my_string = "hi";
Run Code Online (Sandbox Code Playgroud)
在Rust我尝过类似的东西
pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char };
Run Code Online (Sandbox Code Playgroud)
但这抱怨
error: casting `&'static str` as `*const i8` is invalid
Run Code Online (Sandbox Code Playgroud)
似乎我不能使用CString
等因为它们不是编译时常量表达式.
这有点奇怪,所以忍受我...
#[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);
Run Code Online (Sandbox Code Playgroud)
理想情况下,我们可以只有一个公共的,静态的,未拼写的,指向某些字节的常量指针,对吧?但是,当您收到此错误时,您无法执行此操作:
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;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
我没有花很多时间思考为什么会出现这种情况.看起来像一个不可变的指针应该不会造成太大的麻烦......
但是,我们可以告诉编译器我们的类型在多线程环境中使用是安全的.这就是包装类型存在的原因 - 它允许我们实现Sync
我们拥有的类型.单元素结构应始终具有与包装值相同的实现,但我们继续并将其标记为repr(C)
安全.
这适用于简单的C程序:
#include <stdio.h>
extern char * CONST_C_STR;
int main(int argc, char *argv[]) {
printf("%s\n", CONST_C_STR);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1038 次 |
最近记录: |