- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个场景,我们有一个大约 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
memset
和memcpy
很容易修复。我假设的边界检查是在 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/
我是一名优秀的程序员,十分优秀!