I'm writing Rust bindings to a C library which has the option to use a third-party memory allocator. Its interface looks like this:
struct allocator {
void*(*alloc)(void *old, uint);
void(*free)(void*);
};
The corresponding Rust struct is, I guess, the following:
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Allocator {
alloc: Option<extern "C" fn(*mut c_void, c_uint) -> *mut c_void>,
free: Option<extern "C" fn(*mut c_void)>,
}
How can I implement these two extern functions that should mimic the allocator? I did not find anything really looking like the allocator API in Rust (I understand why however), so I'm curious if it is possible.
It's not as easy as you might like.
The allocation methods are exposed in the
heap
module of thealloc
crate.Creating some wrapper methods and populating the struct is straight-forward, but we quickly run into an issue:
The Rust allocator expects to be told the size of any previous allocation as well as the desired alignment. The API you are matching doesn't have any way of passing that along.
Alignment should (I'm not an expert) be OK to hardcode at some value, say 16 bytes. The size is trickier. You will likely need to steal some old C tricks and allocate a little bit extra space to store the size in. You can then store the size and return a pointer just past that.
A completely untested example:
That's certainly possible, but I'm not completely sure how it would work with reallocation. You'd also have to keep track of the size and capacity of the
Vec
in order to reconstitute it to reallocate / drop it.