rust - How can I work around a RefCell issue? -
i have struct 2 c pointers , 1 rust hashmap.
struct mystruct { p1: *mut ..., p2: *mut ..., hm: box<hashmap<...>> } my struct gets handled rc<refcell<mystruct>> , have c function gets called this:
c_call(my_struct.borrow().p1, my_struct.borrow().p2); c has rust callback gets called during execution of c_call requires my_struct.borrow_mut(), my_struct borrowed c_call needs p1 , p2, refcell<t> borrowed.
the problem c_call can't changed , needs immutable access p1 , p2 , borrow_mut of my_struct.
here's 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 borrowed // c_call can't 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 receives rc<refcell<mystruct>> , need 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)
how can work around issue?
your issue calling borrow() in arguments of c_call call borrow object until call finishes. if change to
let (p1, p2) = { let x = my_struct.borrow(); (x.p1, x.p2) }; c_call(p1, p2, my_struct.clone()); then borrow ends before c_call call, c_call can borrow_mut object, too.
Comments
Post a Comment