В документации UnsafeCell
написано
Тип UnsafeCell<T>
является единственным допустимым способом получения псевдонимов, которые считаются изменяемыми.
Единственный метод построения:
pub const fn new(value: T) -> UnsafeCell<T>
Однако невозможно создать c_void
, мы можем создать только *mut c_void
или *const c_void
.
можно создать UnsafeCell<c_void>
из *mut c_void
?При этом мы можем сообщить компилятору, что указатель может указывать на что-то изменяемое.
Или это не обязательно?Можем ли мы всегда использовать *mut c_void
, даже если мы знаем, что какой-то вызов FFI изменяет данные, на которые он указывает, и у нас есть несколько ссылок на него?
Вариант использования:
struct FFIStruct { v: UnsafeCell<c_void>, other_fields: ... }
impl FFIStruct {
// We don't want to require &mut self, as we
// are sure private call_ffi() will always be called
// sequentially, and we don't want to stop
// status() being callable during the call
fn call_ffi(&self){ ffi_function(self.v.get()) }
pub fn status(&self) -> FFIStatus { ... }
}
Теперькак мы создаем FFIStruct
?Или просто использовать *mut c_void
будет в порядке?
Пример кода для создания &Cell<c_void>
Требуется #![feature(as_cell)]
:
unsafe fn get_cell<'a>(p: *mut c_void) -> &'a Cell<c_void> {
Cell::from_mut(&mut *p)
}