如何添加/减去非空的偏移量<Opaque>?



我提供了两个管理内存的函数:

unsafe extern "system" fn alloc<A: Alloc>(
size: usize,
alignment: usize,
) -> *mut c_void { ... }
unsafe extern "system" fn free<A: Alloc>(
memory: *mut c_void
) { ... }

这两个函数在内部都使用分配器 API。

这些签名无法更改。问题是free不要求sizealignment,这是Alloc::dealloc所必需的。为了解决这个问题,alloc为一个Layout分配了一些额外的空间。free现在可以访问此Layout以获取所需的额外数据。

最近,分配器-api发生了变化,而不是*mut u8它现在使用NonNull<Opaque>。这就是我出现问题的地方。

core::alloc::Opaque

不透明、未调整大小的类型。用于指向已分配内存的指针。[...]此类指针类似于 C 的void*类型。

OpaqueSized,因此禁止使用NonNull::as_ptr().add()NonNull::as_ptr().sub()

以前,我使用了这样的东西(为简单起见,我假设Alloc的函数是静态的):

#![feature(allocator_api)]
#![no_std]
extern crate libc;
use core::alloc::{Alloc, Layout};
use libc::c_void;
unsafe extern "system" fn alloc<A: Alloc>(
size: usize,
alignment: usize,
) -> *mut c_void
{
let requested_layout =
Layout::from_size_align(size, alignment).unwrap();
let (layout, padding) = Layout::new::<Layout>()
.extend_packed(requested_layout)
.unwrap();
let ptr = A::alloc(layout).unwrap(); 
(ptr as *mut Layout).write(layout);
ptr.add(padding)
}

最后一行不再可能与NonNull<Opaque>.我该如何解决这个问题?

我可能会这样写,使用NonNull::as_ptr来获取*mut Opaque,然后将其转换为不同的具体类型:

#![feature(allocator_api)]
#![no_std]
extern crate libc;
use core::alloc::{Alloc, Layout};
use libc::c_void;
unsafe fn alloc<A: Alloc>(allocator: &mut A, size: usize, alignment: usize) -> *mut c_void {
let requested_layout = Layout::from_size_align(size, alignment).expect("Invalid layout");
let (layout, _padding) = Layout::new::<Layout>()
.extend_packed(requested_layout)
.expect("Unable to create layout");
let ptr = allocator.alloc(layout).expect("Unable to allocate");
// Get a pointer to our layout storage 
let raw = ptr.as_ptr() as *mut Layout;
// Save it
raw.write(layout);
// Skip over it
raw.offset(1) as *mut _
}

unsafe extern "system" fn alloc<A: Alloc>(

这对我来说毫无意义。各种 FFI ABI("C"、"系统"等)无法指定 Rust 泛型类型。将此功能标记为extern似乎非常不正确。


Layout::new::<Layout>().extend_packed(requested_layout)

这似乎可能非常破碎。正如Layout::extend_packed的文档所述,强调我的:

next的对齐方式无关紧要,并且根本不会合并到生成的布局中

返回的指针似乎不支持对齐请求。

最新更新