2014-09-05 82 views

回答

7

你也可以在Rust中做同樣的事情。您在定義結構時必須小心謹慎。

use std::mem; 

#[repr(C)] 
#[packed] 
struct YourProtoHeader { 
    magic: u8, 
    len: u32 
} 

let mut buf = [0u8, ..1024]; // large enough buffer 

// read header from some Reader (a socket, perhaps) 
reader.read_at_least(mem::size_of::<YourProtoHeader>(), buf.as_mut_slice()).unwrap(); 

let ptr: *const u8 = buf.as_ptr(); 
let ptr: *const YourProtoHeader = ptr as *const YourProtoHeader; 
let ptr: &YourProtoHeader = unsafe { &*ptr }; 

println!("Data length: {}", ptr.len); 

不幸的是,我不知道如何指定緩衝區是完全size_of::<YourProtoHeader>()大小;緩衝區長度必須是一個常量,但size_of()調用在技術上是一個函數,所以Rust在數組初始值設定項中使用它時會抱怨。儘管如此,足夠大的緩衝區也可以工作。

這裏我們將一個指針指向緩衝區的開頭,指向結構的指針。這與C中的操作相同。結構本身應該註釋爲#[repr(C)]和​​屬性:第一個不允許可能的字段重新排序,第二個禁用字段對齊的填充。

+0

我想在這種類型的解析存在的時候,真的沒有辦法繞過不安全的塊。感謝您的解決方案。 – Matt 2014-09-08 12:21:54

+4

@Matt,是的,重新解釋一段內存是非常不安全的。如果你不想'unsafe',你可以將'buf'包裝到'BufReader'中並使用['Reader'](http://doc.rust-lang.org/std/io/trait.Reader.html)方法,比如'read_be_u32()'。無論如何,這可能是一個好主意,因爲重新解釋一段內存不會讓你調整永恆性,所以你的程序不能移植。 – 2014-09-08 12:59:41

相關問題