【问题标题】:How to send c_void to another thread如何将 c_void 发送到另一个线程
【发布时间】:2021-11-16 09:21:10
【问题描述】:

我使用bindgen为相机的C++库创建了一个Rust包装器,C++库中的相机句柄被定义为typedef void camera_handlebindgen被移植为pub type camera_hanlde = ::std::os::raw::c_void

我能够成功连接到相机并拍摄图像,但是我想在单独的线程上运行代码来控制相机的温度,本质上是根据相机的当前温度来改变冷却器的功率,我希望与其余代码分开运行。这些调用需要相机句柄,但是当我生成一个新线程时,我不断收到错误:

'*mut std::ffi::c_void' cannot be sent between threads safely

在它下面,它提到了the trait 'std::marker::Send' is not implemented for '*mut std::ffi::c_void'

如何将它发送到另一个线程,以便我也可以在那里使用这个相机手柄?我对 Rust 有点陌生,曾尝试使用 fragilesend_wrapper 进行包装,但都没有成功。

【问题讨论】:

  • 这与c_void 无关,您尝试发送某些东西的可变指针。那是不允许的
  • @Stargateur 发送一个可变指针很好,它是一个禁止共享的可变引用 - 将指针转换为引用需要一个不安全的块。 Rust 还需要手动且不安全地为指针实现 Send 作为预防措施,并提醒您检查指针是否按照 Rust 的规则使用。如果 OP 只使用 FFI 的指针,它们应该是安全的(前提是外部 API 本身是线程安全的)。

标签: c++ rust ffi void-pointers rust-bindgen


【解决方案1】:

指针不实现SendSync,因为它们的安全性逃脱了编译器。您打算明确指示何时可以安全地跨线程使用指针。这通常是通过您自己实现 Send 和/或 Sync 的包装器类型来完成的:

struct CameraHandle(*mut c_void);

unsafe impl Send for CameraHandle {}
unsafe impl Sync for CameraHandle {}

由于手动实现这些特征是 unsafe,因此您应该格外努力以确保来自外部库的类型实际上可以移动到另一个线程 (Send) 和/或由多个线程共享 (Sync)。

如果您在没有&mut self 保护的情况下利用指针的可变性,它可能应该是Sync,因为同时拥有两个&mut T 总是不合理的。

见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2022-01-04
    • 2017-05-08
    • 2015-07-22
    • 2013-12-02
    相关资源
    最近更新 更多