C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

rust: 任意の Primitive, struct, Vec<T> などのメモリーイメージを Vec< u8 > (≃ &[ u8 ] ) なバイト列として取得する方法

// for rust-1.27.2(stable)

use std::mem;
use std::io::Write;

fn main()
{
  { // f64 (primitive) -> Vec< u8 >
    let f = 1.0f64;
    let view = &f as *const _ as *const u8;
    let slice = unsafe { std::slice::from_raw_parts( view, mem::size_of::< f64 >()) };
    let mut out: Vec< u8 > = vec![];
    out.write( slice ).expect( "Unable to write" );
    println!( "{} => {:?}", f, out );
  }
  { // struct -> Vec< u8 >
    struct S { a: f32, b: [u8;2], c: u16 }
    let s = S { a: 1.234e-5, b: [ 1, 2 ], c: 0x0403 };
    let view = &s as *const _ as *const u8;
    let slice = unsafe { std::slice::from_raw_parts( view, mem::size_of::< S >()) };
    let mut out: Vec< u8 > = vec![];
    out.write( slice ).expect( "Unable to write" );
    println!( "s{{ a: {}, b: {:?}, c:{} }} => {:?}", s.a, s.b, s.c, out );
  }
  { // Vec< 16 > -> Vec< u8 >
    let v16 = vec! [ 0x0000u16, 0x0201, 0x0403, 65535 ];
    let view = &v16[ 0 ] as *const _ as *const u8;
    let slice = unsafe { std::slice::from_raw_parts( view, v16.len() * mem::size_of::< u16 >()) };
    let mut out: Vec< u8 > = vec![];
    out.write( slice ).expect( "Unable to write" );
    println!( "{:?} => {:?}", v16, out );
  }
}
1 => [0, 0, 0, 0, 0, 0, 240, 63]
s{ a: 0.00001234, b: [1, 2], c:1027 } => [229, 7, 79, 55, 3, 4, 1, 2]
[0, 513, 1027, 65535] => [0, 0, 1, 2, 3, 4, 255, 255]

References

  1. rust - How can I get an array or a slice from a raw pointer? - Stack Overflow
  2. std::slice::from_raw_parts - Rust

Note

rust-1.10 までは std::raw::Slice が unstable で実装されていて、この手の方法を調べるとそちらを使う方法も出てくる。 rust-1.9 で deprecated 、 rust-1.11 で obsoleted になったのでそちらは使えないので古い手法、情報による混乱に注意。