0

2 つの C ポインターと 1 つの Rust を持つ構造体がありHashMapます。

struct MyStruct {
    p1: *mut ...,
    p2: *mut ...,
    hm: Box<HashMap<...>>
}

私の構造体は として処理され、次のRc<RefCell<MyStruct>>ように呼び出される C 関数があります。

c_call(my_struct.borrow().p1, my_struct.borrow().p2);

c_callC には、を必要とするの実行中に呼び出される Rust コールバックがありますが、 とmy_struct.borrow_mut()が必要なmy_structために既に借用されているため、 を取得します。c_callp1p2RefCell<T> already borrowed

問題は、変更できないことと、および の一部c_callへの不変のアクセスが必要なことです。p1p2borrow_mutmy_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);
    }
}

(ベビーサークル)

この問題を回避するにはどうすればよいですか?

4

2 に答える 2