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