1 个不稳定版本
0.1.0 | 2023 年 8 月 9 日 |
---|
#2223 在 Rust 模式
55KB
702 行
gep
gep
,一个更好的指针算术库。
名称 gep
来自 LLVM 的 getelementptr
指令,臭名昭著的指针算术操作。
该库提供了两种新的指针类型,[Ptr::at()
] 和 NonNull::
,它们具有非常相似的 API;分别对应于 *mut T
和 core::ptr::NonNull
。
它还提供了 Rust 版本的 memcpy
、memmove
和 memset
。
偏移量
该库提供的首要操作是 [Ptr::at()
],这是一个通用的指针算术操作。例如,它将接受任何整数作为输入,而不仅仅是 isize
(尽管,像 [<*mut T>::offset
],偏移量值必须是有效的,可以转换为 isize
)。
let mut ints = [0i32; 6];
let p = Ptr::from(&mut ints).element();
unsafe {
// Pointer to the 4th element.
let q = p.at(4);
q.write(42);
// Many operations have an `*_at` variant that internally calls .at().
q.write_at(-1, 55);
}
assert_eq!(ints, [0, 0, 0, 55, 42, 0]);
默认情况下,at()
在元素的多倍上工作。要进行直接字节偏移,可以使用 offset::ByteOffset
类型。
use gep::offset::ByteOffset;
let mut ints = [0i32; 6];
let p = Ptr::from(&mut ints).element();
unsafe {
p.write_at(ByteOffset(4), 4242);
}
assert_eq!(ints[1], 4242);
也可以使用“字段偏移量”(通过offset::Field
类型)直接访问结构体的字段,而无需创建指向可能无效数据的中间引用。
use gep::offset::Field;
struct Foo {
a: i32,
b: [i32; 3],
}
let foo = Foo { a: 0, b: [1, 2, 3] };
let p = Ptr::from(&foo);
let value = unsafe {
p.read_at(gep::field!(Foo.b[1]))
};
assert_eq!(value, 2);
许可证:Apache-2.0