当前位置: 首页 > 工具软件 > transmute > 使用案例 >

015 Rust死灵书之Transmutes转换

冉锋
2023-12-01

本系列录制的视频主要放在B站上Rust死灵书学习视频

Rust 死灵书相关的源码资料在https://github.com/anonymousGiga/Rustonomicon-Source

介绍

mem::transmute<T, U> 接受一个 T 类型的值,然后将它重新解析为类型 U。要求T和U的大小一样。
这种操作是非安全的行为,可能产生未定义的行为。

示例

1、字节到类型转换

u32::from_ne_bytes  从内存转换到native字节序列类型
u32::from_be_bytes 从内存转换到大端序列类型
u32::from_le_bytes 从内存转换到小端序列类型

2、transmute

pub const unsafe extern "rust-intrinsic" fn transmute<T, U>(e: T) -> U
将一种类型的值重新解释为另一种类型。它将源值中的位复制到目标值中,然后忘记原始值。

例子:

//std::mem::transmute
//将连续的字节转换成另外一个类型,会产生为定义的行为

fn main() {
	//let raw_bytes = [0x78, 0x56, 0x34, 0x12];
	let mut raw_bytes = [0x78, 0x56, 0x34, 0x12];
	let num = unsafe {
	    std::mem::transmute::<[u8; 4], u32>(raw_bytes)
	};
	let ret = u32::from_ne_bytes(raw_bytes);

	//assert_eq!(num, 0x12345678);
	assert_eq!(num, ret);
	println!("num = {}", num);
}

3、transmute_copy

pub unsafe fn transmute_copy<T, U>(src: &T) -> U
将src解释为&U类型,然后读取src的值。读取时是创建副本,而不是直接移动。

例子:

use std::mem;

#[repr(packed)]
struct Foo {
    bar: u8,
}

fn main() {
	let foo_array = [10u8];
	
	unsafe {
	    let mut foo_struct: Foo = mem::transmute_copy(&foo_array);
	    assert_eq!(foo_struct.bar, 10);
	
	    foo_struct.bar = 20;
	    assert_eq!(foo_struct.bar, 20);
	}
	
	assert_eq!(foo_array, [10]);
}
 类似资料: