mem::offset_of!() 宏
这个宏用于获取结构体成员的相对于结构体起始内存的偏移量, 类似于 libc 中的 offsetof()
函数.
下面是一个示例程序:
#![allow(non_camel_case_types)] use std::mem; // rustc 决定内存布局 pub struct linux_dirent_t { pub d_ino: u64, pub d_off: u64, pub d_reclen: u16, pub d_type: u8, pub d_name: *mut u8, } // 使用 C ABI 兼容的内存布局 #[repr(C)] pub struct linux_dirent_c_t { pub d_ino: u64, pub d_off: u64, pub d_reclen: u16, pub d_type: u8, pub d_name: *const u8, } // 为结构体添加 packed attribute, 忽略结构体内成员的内存对齐. #[repr(packed)] pub struct linux_dirent_packed_t { pub d_ino: u64, pub d_off: u64, pub d_reclen: u16, pub d_type: u8, pub d_name: *const u8, } fn main() { assert_eq!(mem::offset_of!(linux_dirent_t, d_name), 16); assert_eq!(mem::offset_of!(linux_dirent_c_t, d_name), 24); assert_eq!(mem::offset_of!(linux_dirent_packed_t, d_name), 19); }
对应的 C 代码如下:
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
struct linux_dirent_s {
uint64_t d_ino;
uint64_t d_off;
uint16_t d_reclen;
uint8_t d_type;
char* d_name;
};
struct linux_dirent_packed_s {
uint64_t d_ino;
uint64_t d_off;
uint16_t d_reclen;
uint8_t d_type;
char* d_name;
} __attribute__((packed));
int main(void) {
assert(offsetof(struct linux_dirent_s, d_name) == 24);
assert(offsetof(struct linux_dirent_packed_s, d_name) == 19);
return 0;
}