Можно ли использовать Vec(u8)
для этой цели?
Вектор не должен использоваться таким образом, даже если ваш код должен работать, это не хороший метод.
Чтобы сделать это правильно, вам нужна экспериментальная функция (эта довольно стабильная), вам нужно использовать структуру System
и черту Alloc
. К сожалению, ваша библиотека не предъявляет никаких требований к выравниванию для своего дескриптора, поэтому мы должны использовать 1
.
pub type Handle = *mut u8;
неверно в соответствии с вашим typedef void* handle;
(кстати, указатель hide неверен). Это должно быть pub type Handle = *mut libc::c_void;
.
#![feature(allocator_api)]
use std::alloc::{Alloc, Layout, System};
use std::ptr::NonNull;
pub struct Island {
handle: NonNull<u8>,
layout: Layout,
}
impl Island {
pub fn new() -> Island {
let size = unsafe { lib_handle_size() };
let layout = Layout::from_size_align(size, 1).unwrap();
let handle = unsafe { System.alloc(layout).unwrap() };
unsafe {
// can have error I guess ?
lib_init(handle.as_ptr() as Handle);
}
Self { handle, layout }
}
pub fn store(&mut self, v: i32) -> Result<(), ()> {
unsafe {
lib_store(self.handle.as_ptr() as Handle, v);
}
Ok(())
}
pub fn restore(&mut self, v: &mut i32) -> Result<(), ()> {
unsafe {
lib_restore(self.handle.as_ptr() as Handle, v);
}
Ok(())
}
}
impl Drop for Island {
fn drop(&mut self) {
unsafe { System.dealloc(self.handle, self.layout) }
}
}
/// unsafe part
use libc::size_t;
pub type Handle = *mut libc::c_void;
#[link(name = "cisland")]
extern "C" {
pub fn lib_handle_size() -> size_t;
pub fn lib_init(h: Handle) -> i32;
pub fn lib_store(h: Handle, value: i32) -> i32;
pub fn lib_restore(h: Handle, pvalue: &mut i32) -> i32;
}
Я немного изменил вашу функцию store()
и restore()
, чтобы вернуть Result. Могу поспорить, что ваша функция C делает то же самое.