ฉันจะสร้างพอยน์เตอร์ที่ไม่ได้เตรียมใช้งานซึ่งฉันสามารถส่งผ่านไปยังฟังก์ชัน FFI ในลักษณะที่ปลอดภัยสำหรับเธรดได้อย่างไร

ฉันมีโค้ด Rust บางตัวที่ส่งพอยน์เตอร์ไปยังฟังก์ชัน FFI เช่นนี้

let mut mu = MaybeUninit::uninit();
let mut p = mu.as_mut_ptr();

let r = unsafe {
    ffi_fn(&mut p)
};

วิธีนี้ใช้ได้ดีกับเธรดเดียว แต่สำหรับหลายเธรด ฉันคิดว่า MaybeUninit::uninit() จะให้ตัวชี้เดียวกันไปยังสองเธรดพร้อมกัน ซึ่งทำให้เกิดปัญหา


person zino    schedule 29.09.2019    source แหล่งที่มา
comment
เหตุใดคุณจึงต้องการส่งพอยน์เตอร์ที่ไม่ได้กำหนดค่าเริ่มต้นไปยังฟังก์ชัน   -  person mcarton    schedule 29.09.2019
comment
อาจมีหลายวิธีในการเพิ่มเธรดให้กับโปรแกรม เราต้องการข้อมูลเพิ่มเติม ฉันไม่เห็นว่า MaybeUninit เกี่ยวข้องอะไรกับว่าตัวชี้เหมือนกันสำหรับหลายเธรดหรือไม่   -  person trentcl    schedule 29.09.2019
comment
@mcarton เช่น sqlite3_open ใช้ตัวชี้เป็นอาร์กิวเมนต์ที่ 2 sqlite.org/c3ref/open.html   -  person zino    schedule 29.09.2019
comment
ในกรณีนั้น คุณสามารถให้ null ได้ แต่เช่นเดียวกับ @trentcl ฉันไม่คิดว่าคำถามของคุณมีข้อมูลไม่เพียงพอที่จะตอบคำถาม โดยเฉพาะอย่างยิ่ง สิ่งนี้ไม่เกี่ยวข้องกับเธรด และฉันไม่เห็นว่าเหตุใดจึงเป็นปัญหาในการให้ค่าเดียวกันกับฟังก์ชันนี้พร้อมกัน   -  person mcarton    schedule 29.09.2019
comment
หาก sqlite3_open นำตัวชี้ที่ไม่แน่นอนไปยังตัวชี้ที่ไม่แน่นอนไปยังบางสิ่งบางอย่าง ตัวชี้แรก (สิ่งที่อยู่ใน MaybeUninit) จะไม่เกี่ยวข้อง เนื่องจากทันทีที่ค่าใต้ตัวชี้ด้านนอกสุดถูกแทนที่ ค่านั้นจะแตกต่างจากค่าที่ MaybeUninit เก็บไว้ เพียงใช้ std::ptr::null หรือ std::ptr::null_mut   -  person Optimistic Peach    schedule 29.09.2019


คำตอบ (1)


ตามที่ Optimistic Peach และ trentcl ชี้ให้เห็นในความคิดเห็น วิธีที่ถูกต้องในการทำเช่นนี้คือการดึงข้อมูลตัวชี้ null (ตัวอย่างสนามเด็กเล่น):

let ptr: *mut i8 = std::ptr::null_mut();
let ptr_to_ptr: *const *mut i8 = &ptr;

ลักษณะการทำงานเช่นเดียวกับ C ที่ใช้: แม้ว่าตัวชี้เองจะเป็น NULL แต่ตัวชี้ไปยังที่อยู่นี้เป็นที่อยู่ที่ถูกต้องในหน่วยความจำ จากนั้นจะขึ้นอยู่กับอีกด้านหนึ่งของขอบเขต FFI ในการเปลี่ยนที่อยู่นี้เป็นอย่างอื่นที่ไม่ใช่ 0x0 และคุณจะได้รับการเปลี่ยนแปลงนั้น (เนื่องจากคุณมีการอ้างอิงโดยตรงถึงที่อยู่นี้ด้วย)

person Sébastien Renauld    schedule 30.09.2019