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(C, 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;
}