У меня есть структура с двумя указателями C и одной Rust HashMap
.Как я могу обойти проблему RefCell?
struct MyStruct {
p1: *mut ...,
p2: *mut ...,
hm: Box<HashMap<...>>
}
Моя структура получает обрабатывается как Rc<RefCell<MyStruct>>
и у меня есть функция C, который вызывается так:
c_call(my_struct.borrow().p1, my_struct.borrow().p2);
C имеет обратный вызов Rust, который вызывается во время выполнения c_call
, что требует my_struct.borrow_mut()
, но my_struct
уже занят для c_call
, которому нужны p1
и p2
, поэтому я получаю RefCell<T> already borrowed
.
Проблема заключается в том, что c_call
не может быть изменена, и она нуждается в непреложный доступ к p1
и p2
и некоторые borrow_mut
из my_struct
.
Вот MCVE:
use std::cell::RefCell;
use std::collections::HashMap;
use std::mem::uninitialized;
use std::os::raw::c_void;
use std::rc::Rc;
struct MyStruct {
p1: *mut c_void,
p2: *mut c_void,
hm: Box<HashMap<String, String>>
}
// c_call can't mutate hm because my_struct is already borrowed
// c_call can't be changed
fn c_call(_p1: *mut c_void, _p2: *mut c_void, my_struct: Rc<RefCell<MyStruct>>) {
my_struct.borrow_mut().hm.insert("hey".to_string(), "you".to_string());
}
// call only receives Rc<RefCell<MyStruct>> and need to call c_call
fn call(my_struct: Rc<RefCell<MyStruct>>) {
c_call(my_struct.borrow().p1, my_struct.borrow().p2, my_struct.clone());
}
fn main() {
unsafe {
let my_struct = MyStruct {
p1: uninitialized::<*mut c_void>(), // irrelevant
p2: uninitialized::<*mut c_void>(),
hm: Box::new(HashMap::new())
};
let my_struct = Rc::new(RefCell::new(my_struct));
call(my_struct);
}
}
(Playpen)
Как я могу обойти эту проблему?
Есть ли причина, по которой вы не можете просто скопировать 'p1' и' p2' из 'my_struct'? В конце концов, это просто странные типизированные числа ... –
Тогда вам придется переместить 'RefCell' в поле' hm', а затем 'p1' и' p2' больше не могут быть изменены. –
BTW, ящик вокруг HashMap почти наверняка бессмыслен, вы можете просто сохранить HashMap напрямую. – delnan