问题
While raw pointers in Rust have the offset method, this only increments by the size of the pointer. How can I get access to the pointer in bytes?
Something like this in C:
var_offset = (typeof(var))((char *)(var) + offset);
回答1:
From the answer I linked to your previous question:
macro_rules! offset_of {
($ty:ty, $field:ident) => {
unsafe { &(*(0 as *const $ty)).$field as *const _ as usize }
}
}
fn main() {
let p: *const Baz = 0x1248 as *const _;
let p2: *const Foo = ((p as usize) - offset_of!(Foo, memberB)) as *const _;
println!("{:p}", p2);
}
We can see on the computation of p2 that a pointer can be converted painless to an integer (usize here), on which arithmetic is performed, and then the result is cast back to a pointer.
isize and usize are the universal byte-sized pointer types :)
回答2:
Thanks to @Matthieu M.'s answer, this can be done using pointer offsets, heres a reusable macro:
macro_rules! offset_of {
($ty:ty, $field:ident) => {
&(*(0 as *const $ty)).$field as *const _ as usize
}
}
macro_rules! check_type_pair {
($a:expr, $b:expr) => {
if false {
let _type_check = if false {$a} else {$b};
}
}
}
macro_rules! parent_of_mut {
($child:expr, $ty:ty, $field:ident) => {
{
check_type_pair!(&(*(0 as *const $ty)).$field, &$child);
let offset = offset_of!($ty, $field);
&mut *(((($child as *mut _) as usize) - offset) as *mut $ty)
}
}
}
macro_rules! parent_of {
($child:expr, $ty:ty, $field:ident) => {
{
check_type_pair!(&(*(0 as *const $ty)).$field, &$child);
let offset = offset_of!($ty, $field);
&*(((($child as *const _) as usize) - offset) as *const $ty)
}
}
}
This way, when we have a field in a struct, we can get the parent struct like this:
fn some_method(&self) {
// Where 'self' is ParentStruct.field,
// access ParentStruct instance.
let parent = unsafe { parent_of!(self, ParentStruct, field) };
}
The macro check_type_pair helps avoid simple mistakes where self and ParentStruct.field aren't the same type. However its not foolproof when two different members in a struct have the same type.
来源:https://stackoverflow.com/questions/40310483/how-to-get-pointer-offset-in-bytes