我有一個場景,我們有一個15年前用C編寫的現有(舊)操作系統。現在,我們正在考慮擴展這個系統,能夠在Rust中編寫用戶空間程序。如何將&str轉換爲* const i8 *而不使用* libstd和libcore?
當然,因爲這是最近開始的,我們並沒有考慮將所有的libstd
移植到我們自己的操作系統。因此我們使用#![feature(no_std)]
。
現在,我正在尋找一些應該合理簡單的東西:將Rust字符串轉換爲C空終止的字符串。應該很簡單,但是因爲我對Rust沒有經驗,所以我還沒有弄清楚。
爲了這個經驗,強加一定的限制就足夠了(比如,最大1024字節長的字符串;其他任何被截斷)。 (我們也有到位的內存分配,但我沒有打擾試圖從防鏽處理內存分配還)
這是迄今爲止我愚蠢的嘗試:
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菲捨爾的答案,我改變了我的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的情況下工作? (無論如何這可能是一個合理的東西......)
重要的一點是:因爲'as_ptr'消耗'self',所以會得到代碼進行編譯,但返回值將是一個懸掛指針。 – fjh
哪個as_ptr是?聽起來像是誤會。 – bluss
來自OP的示例代碼的'pub fn as_ptr(self) - > * const i8'。由於它的值是'self',所以'CString'實例將在函數結束時被釋放,這意味着你要返回一個指向釋放內存的指針。 –