Hello,
I'm trying to implement a plugin (dynamic library/dylib) for another (closed source) program.
The API I have to implement is provided in c, and I am pretty used to working with c, but took this as a challenge to implement it in Rust (and learn Rust on the way).
Basically I must implement an Init
function that's called by the program, one of the parameters is a pointer to a struct containing function pointers, including alloc/free/realloc.
I'm trying to figure out how to write a custom allocator that will use those provided functions, and enforce it's use across the whole lib.
Due to licensing I cannot post the API, but here's the gist of it:
/* C Header */
typedef struct {
void (*Free) (void* p);
void* (*Alloc) (unsigned size);
void* (*Realloc) (void* p, unsigned size);
} api_t;
int Init(api_t const *p_api);
// Other API functions...
Here's a snippet of what I've got so far in Rust:
//! lib.rs
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct api_t {
pub Free: Option<unsafe extern "C" fn(p: *mut c_void)>,
pub Alloc: Option<unsafe extern "C" fn(size: c_uint) -> *mut c_void>,
pub Realloc: Option<unsafe extern "C" fn(p: *mut c_void, size: c_uint) -> *mut c_void>
}
static mut API:api_t = api_t {
Free: Option::None,
Alloc: Option::None,
Realloc: Option::None,
};
#[no_mangle]
pub extern "C" fn Init(p_api: *const api_t) -> c_int {
if p_api.is_null() {
return -1;
}
unsafe {
API = *p_api;
}
1
}
It is guaranteed that Init is the first function that gets called from my lib.
I considered writing a custom allocator (Custom Allocators) as a nested crate in my project, and add some kind of init function to it, which will get an immutable copy of the API struct and keep it as a static var, similarly to what I did in the snippet above.
Would that be feasible?
Any help would be greatly appreciated.