簡體   English   中英

如何將復制整數值長度后跟由該值組成的字節字符串的 C 代碼轉換為任意字節?

[英]How can I translate C code that copies the length of an integer value followed by a byte string consisting of the value into arbitrary bytes?

我正在使用此 C 代碼將幾個值編碼為一個字節字符串:

unsigned char *buf = malloc(10);
*(unsigned int *)buf = 6;
memcpy(buf + 4, source, 6);
// Repeat for more values...

它復制一個uint32 ,其長度為值,后跟由該值組成的字節字符串。

如何在 Rust 中做到這一點? 似乎沒有一種直接的方法(我知道)以任意對齊方式和寬度操作內存。

user4815162342 的回答提供了直接翻譯。 這是一個更慣用的 Rust 方法:

use byteorder::{BigEndian, WriteBytesExt}; // 1.3.4
use std::io::Write;

fn main() {
    let source = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let mut buff = Vec::with_capacity(10);
    buff.write_i32::<BigEndian>(6).unwrap();
    buff.write(&source).unwrap();
}

這是有效的,因為Write trait 是為Vec<u8>

使用byteorder crate 允許您指定要寫入長度的字節序。

與 C 版本有一些區別:

  • write會根據需要擴展緩沖區的大小(盡管如果您以所需的大小開始創建它會更有效)

  • write返回一個Result指示是否有錯誤。 在這個示例中,我選擇解包結果,如果出現錯誤,這將導致恐慌。 然而,正如@shepmaster 所指出的, 目前在Vec上實現write只會返回一個Ok變體,因此您可以通過像這樣丟棄它來減少檢查結果的開銷:

     let _ = buff.write(&source);

您的示例非常低級; 如果您告訴我們您想要實現的高級目標,那將會有所幫助,我們也許可以推薦一種在 Rust 中實現的優雅方法。

但是,Rust 是一種系統語言,因此絕對可以將您的代碼翻譯成 Rust,只要考慮到它:a) 不安全,b) 不優雅。 所謂unsafe ,我的意思是您實際上需要使用unsafe來允許不受保護地寫入指針,並且比喻錯誤可能很容易導致未定義的行為。 而且它並不優雅,因為通常有更好的方法來實現相同的功能。

話雖如此,這里是 C 代碼的直接翻譯:

use std::alloc::{self, Layout};
use std::{mem, ptr};

fn main() {
    let source = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    unsafe {
        let layout = Layout::from_size_align(10, mem::align_of::<i32>()).unwrap();
        let buf = alloc::alloc(layout);     // buf = malloc(10)
        *(buf as *mut i32) = 6;             // *(unsigned int *)buf = 6;
        ptr::copy(source.as_ptr(), buf, 6); // memcpy(buf, source, 6);
        // fill the rest of buf with something, otherwise UB on read

        // use buf...

        alloc::dealloc(buf, layout);        // free(buf)
    }
}

這種代碼幾乎從不通常用 Rust 程序編寫。 它用於特殊情況,例如在實現提供現有 crate 尚未涵蓋的安全抽象的 crate 時,並極其謹慎地進行審查。 例如,此答案中編寫的代碼最初包含一個評論者善意指出的重要錯誤(現已修復)。 此外,該代碼不會檢查分配失敗(但問題中的原始 C 代碼也不會)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM