簡體   English   中英

將“* mut * mut f32”轉換為“&[&[f32]]”

[英]Convert “*mut *mut f32” into “&[&[f32]]”

我想轉換數組。

例:

func()-> *mut *mut f32;
...
let buffer = func();
for n in 0..48000 {
    buffer[0][n] = 1.0;
    buffer[1][n] = 3.0;
}

在Rust &[T] / &mut [T]中稱為切片。 切片不是數組; 它是指向數組開頭此數組中項目數的指針。 因此,要創建&mut [T] out *mut T ,您需要知道指針后面的數組的長度。

*mut *mut T看起來像一個2D,可能是鋸齒狀的數組的C實現,即一個數組數組(這與連續的2D數組不同,你可能知道)。 沒有自由的方法將它轉換為&mut [&mut [T]] ,因為正如我之前所說, *mut T是一個指針大小的數字,而&mut [T]是兩個指針大小的數字。 所以你不能,例如,將*mut T&mut [T] ,這將是一個大小不匹配。 因此,由於布局不匹配,您無法簡單地將*mut *mut f32&mut [&mut [f32]]

為了安全地處理存儲在*mut *mut f32 ,首先需要確定外部數組的長度和所有內部數組的長度。 為簡單起見,讓我們考慮一下靜態地知道它們:

const ROWS: usize = 48000;
const COLUMNS: usize = 48000;

現在,既然知道了長度,就可以將外部指針轉換為原始指針切片:

use std::slice;

let buffer: *mut *mut f32 = func();

let buf_slice: &mut [*mut f32] = unsafe {
    slice::from_raw_parts_mut(buffer, ROWS);
};

現在,您需要瀏覽此切片並將每個項目轉換為切片,將結果收集到矢量中:

let matrix: Vec<&mut [f32]> = buf_slice.iter_mut()
    .map(|p| unsafe { slice::from_raw_parts_mut(p, COLUMNS) })
    .collect();

現在您確實可以通過索引訪問緩沖區:

for n in 0..COLUMNS {
    matrix[0][n] = 1.0;
    matrix[1][n] = 3.0;
}

(為了便於閱讀,我在綁定上放置了顯式類型,其中大多數實際上都可以省略)

因此,將原始指針轉換為切片時需要考慮兩件事:

  1. 你需要知道數組的確切長度才能從中創建一個切片; 如果您知道,可以使用slice::from_raw_parts()slice::from_raw_parts_mut() ;
  2. 如果要轉換嵌套數組,則需要重建間接的每一層,因為指針的大小與切片不同。

當然,您必須跟蹤誰是緩沖區的所有者以及何時將其釋放,否則您可以輕松獲得指向不再存在的緩沖區的切片。 畢竟,這是unsafe

由於您的數組似乎是一個指向48000 f32 s數組的指針數組,因此您只需使用固定大小的數組( [T; N] )而不是切片( [T] ):

fn func() -> *mut *mut f32 { unimplemented!() }

fn main() {
    let buffer = func();
    let buffer: &mut [&mut [f32; 48000]; 2] = unsafe { std::mem::transmute(buffer) };
    for n in 0..48000 {
        buffer[0][n] = 1.0;
        buffer[1][n] = 3.0;
    }
}

暫無
暫無

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

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