通过 &str 获取指针
Getting pointer by &str
考虑这个伪代码:
let k = 10;
let ptr = &k as *const k;
println!("{:p}", ptr); // prints address of pointer
let addr = format!("{:p}", ptr);
super-unsafe {
// this would obviously be super unsafe. It may even cause a STATUS_ACCESS_VIOLATION if you try getting memory from a page that the OS didn't allocate to the program!
let ptr_gen = PointerFactory::from_str(addr.as_str());
assert_eq!(k, *ptr_gen);
}
伪代码传达了这个想法:我希望能够通过其 &str 表示形式获得指向某个内存地址的指针。这……可能吗?
所以基本上你想要做的是将字符串解析回一个整数(usize
),然后将该值解释为 pointer/reference† :
fn main()
{
let i = 12i32;
let r = format!("{:p}", &i);
let x = unsafe
{
let r = r.trim_start_matches("0x");
&*(usize::from_str_radix(&r, 16).unwrap() as *const i32)
};
println!("{}", x);
}
您可以在 playground 中自己尝试。
†如您所见,您甚至不需要将引用转换为原始指针,{:p}
格式化程序负责将其表示为内存位置(索引)。
更新:正如E_net4在评论部分提到的,这里最好使用usize
,这是架构定义的,不像机器大小一。 transmute
不是必需的,所以我删除了它。然而,关于未定义行为的第三点对于任何试图做上述事情的人来说似乎是显而易见的。这个答案提供了一种实现 OP 要求的方法,这并不意味着它应该用于 academic/experimental 以外的任何目的:)
考虑这个伪代码:
let k = 10;
let ptr = &k as *const k;
println!("{:p}", ptr); // prints address of pointer
let addr = format!("{:p}", ptr);
super-unsafe {
// this would obviously be super unsafe. It may even cause a STATUS_ACCESS_VIOLATION if you try getting memory from a page that the OS didn't allocate to the program!
let ptr_gen = PointerFactory::from_str(addr.as_str());
assert_eq!(k, *ptr_gen);
}
伪代码传达了这个想法:我希望能够通过其 &str 表示形式获得指向某个内存地址的指针。这……可能吗?
所以基本上你想要做的是将字符串解析回一个整数(usize
),然后将该值解释为 pointer/reference† :
fn main()
{
let i = 12i32;
let r = format!("{:p}", &i);
let x = unsafe
{
let r = r.trim_start_matches("0x");
&*(usize::from_str_radix(&r, 16).unwrap() as *const i32)
};
println!("{}", x);
}
您可以在 playground 中自己尝试。
†如您所见,您甚至不需要将引用转换为原始指针,{:p}
格式化程序负责将其表示为内存位置(索引)。
更新:正如E_net4在评论部分提到的,这里最好使用usize
,这是架构定义的,不像机器大小一。 transmute
不是必需的,所以我删除了它。然而,关于未定义行为的第三点对于任何试图做上述事情的人来说似乎是显而易见的。这个答案提供了一种实现 OP 要求的方法,这并不意味着它应该用于 academic/experimental 以外的任何目的:)