gpt4 book ai didi

string - 如何从 &str 转换为 *const i8 *without* libstd 和 libcore?

转载 作者:行者123 更新时间:2023-11-29 08:11:39 26 4
gpt4 key购买 nike

我有一个场景,我们有一个大约 15 年前用 C 编写的现有(旧)操作系统。现在,我们正在考虑扩展这个系统,能够用 Rust 编写用户空间程序。

自然地,因为这是最近才开始的,我们还没有费心将所有 libstd 移植到我们自己的操作系统上。因此,我们使用 #![feature(no_std)]

现在,我正在寻找一些应该相当简单的东西:将 Rust 字符串转换为以 C-null 结尾的字符串。应该很简单,但由于我对 Rust 缺乏经验,所以我(还)无法弄清楚。

为了这种体验,施加某些限制就足够了(例如,最大 1024 字节长的字符串;其他任何内容都会被截断)。 (我们确实有内存分配,但我还没有费心尝试处理 Rust 的内存分配)

到目前为止,这是我微弱的尝试:

pub struct CString {
buffer: [i8; 1024]
}

impl CString {
pub fn new(s: &str) -> CString {
CString {
buffer: CString::to_c_string(s)
}
}

fn to_c_string(s: &str) -> [i8; 1024] {
let buffer: [i8; 1024];
let mut i = 0;

// TODO: ignore the risk for buffer overruns for now. :)
// TODO: likewise with UTF8; assume that we are ASCII-only.
for c in s.chars() {
buffer[i] = c as i8;
i = i + 1;
}

buffer[s.len()] = '\0' as i8;
buffer;
}

pub fn as_ptr(&self) -> *const i8 {
// TODO: Implement. The line below doesn't even compile.
self.buffer as *const i8
}
}

这里的核心问题是as_ptr中的类型转换。你如何在 Rust 中做到这一点?另外,除了明显的问题之外,这段代码还有其他问题吗? (损坏的 UTF8 非 ASCII 字符处理,如果字符串超过 1024 个字符则完全愚蠢...:)

非常感谢!这必须是相当明显的东西......


更新:根据 Will Fischer 的回答(谢谢!),我将 as_ptr 方法更改为如下所示:

pub fn as_ptr(&self) -> *const i8 {
&self.buffer as *const i8
}

代码现在可以编译了,但是没有链接:

virtio_net_pci.0.rs:(.text._ZN6system8c_string7CString3new20hbfc6c6db748de66bpaaE+0x31): undefined reference to `memset'
virtio_net_pci.0.rs:(.text._ZN6system8c_string7CString3new20hbfc6c6db748de66bpaaE+0x14f): undefined reference to `memcpy'
virtio_net_pci.0.rs:(.text._ZN6system8c_string7CString3new20hbfc6c6db748de66bpaaE+0x174): undefined reference to `panicking::panic_bounds_check::h0b7be17a72a754b5P6E'
virtio_net_pci.0.rs:(.text._ZN6system8c_string7CString3new20hbfc6c6db748de66bpaaE+0x18c): undefined reference to `panicking::panic_bounds_check::h0b7be17a72a754b5P6E'
collect2: error: ld returned 1 exit status

memsetmemcpy 很容易修复。我假设的边界检查是在 libcore 中实现的——有什么方法可以在不链接到 libcore 的情况下让它工作? (无论如何这可能是一件合理的事情......)

最佳答案

不是转换缓冲区,而是转换对缓冲区的引用。 Example

fn main() {
let buffer: [i8; 1024] = [42; 1024];
let ptr: *const i8 = &buffer as *const i8;
unsafe {
println!("{}", *ptr.offset(30));
}
}

您是否尝试过让您的代码与 libcore 一起工作? ?它是标准库的一个子集,涵盖了不需要操作系统支持的所有内容。您可以通过它获得字符串操作函数。

关于string - 如何从 &str 转换为 *const i8 *without* libstd 和 libcore?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32786246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com