我该如何在Rust中创建并传递一个以空字符结尾的C字符串数组(char**)?

10

我正在尝试使用#![no_std]extern crate rlibc编写新的初始化系统,并使用asm调用系统调用,目前尝试避免分配内存。因此,我可以使用的工具范围受到限制。

我需要调用execve系统调用,它需要一个char **argv和一个char **envp。我可以使用零作为字节数组来拼凑c风格字符串,但是如何对静态声明的此类列表进行空值终止(最后一个指针为NULL)呢

1个回答

7

经过沉睡,我想到了答案,现在对我来说似乎很明显。使用整数的切片,并将最后一个设置为0。

// Execute something as an example:
let filename: &[u8] = b"/usr/bin/sensors\x00";     // <-- Make c strings like this
let argv1: &[u8] = b"/usr/bin/sensors\x00";
let argv2: &[u8] = b"-h\x00";
let argv: &[int] = [                               // <-- store them in this
    ::core::intrinsics::transmute(argv1.as_ptr()), // <-- transmuting 
    ::core::intrinsics::transmute(argv2.as_ptr()),
    0                                              // <-- and NULL terminate
];
let envp: &[int] = [0];

::linux64::execve(filename,argv,envp);

2
你应该使用 *const u8 而不是 intas_ptr() 方法已经返回了一个 *const u8,所以你可以直接移除 transmute。要获取一个空指针,请使用 ptr::null()(或 0 as *const T)而不是 0 - Francis Gagné
жӯӨеӨ–пјҢжӮЁеҸҜд»ҘеңЁеӯ—иҠӮдёІдёӯдҪҝз”Ё\0д»Јжӣҝ\x00жқҘиЎЁзӨәз©әеӯ—иҠӮгҖӮ - Francis Gagné
1
你可以自由地将原始指针强制转换为整数,比如(argv1.as_ptr() as int),但正如@FrancisGagné所建议的,最好存储一个&[*const u8]。另外,你是否知道关键字use,它允许将名称引入作用域,例如use core::mem; ... mem::transmute(...) - huon
@FrancisGagné:谢谢你,我希望有人能对这些类型发表评论。 - Ant Manelope
@dbaupp 我不知道转换是如此简单的。是的,我知道use,但目前我更喜欢看到完整的路径。 - Ant Manelope

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