如果将结构移动到其他位置,Rust中是否有任何特征可以得到通知?

Mat*_*mer 2 embedded move ffi rust

在微控制器的Rust和C代码的混合中,我有一个Rust数据结构,我必须知道我的程序的C部分.我得到了这个工作.

pub struct SerialPort {
    // ... some attributes ...
}
Run Code Online (Sandbox Code Playgroud)

我试图重构Rust代码,并希望在一个函数中生成Rust结构,该函数还在我的C代码中注册回调.

pub fn setup_new_port() -> SerialPort {
    let port = SerialPort::new();
    port.register_with_c_code();
    port
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为SerialPort当函数返回时,Rust会将我的类型变量的内存内容移动到不同的位置.在C代码中注册的地址指向(现已释放的)setup_new_port()堆栈帧,当它被移动到调用者的堆栈帧时,因此我的C代码将访问无效地址.

是否有任何我可以实施的特征在移动发生时得到通知?我可以在特征的实现中调整我的C代码中注册的地址.

我知道我可以通过在堆上分配我的结构来防止移动发生,但是我想避免这种情况,因为代码在微控制器上运行并且动态内存分配可能并不总是存在.

Mat*_* M. 8

不,按设计.

Rust是专门设计的,没有所谓的移动构造函数,在Rust中,移动是一个按位复制,允许许多优化:

  • 比如使用C memcpyrealloc,
  • 基于在panic!移动过程中无法调用的事实进行优化,
  • ...

实际上,在C++中有提议来改进这样的设计(is_relocatable),性能是主要的驱动因素.


所以呢?

这样Mutex做吧!也就是说,Box无论什么都不应该移动,并将其隔离在不透明的地方,struct这样任何人都无法将内容移出盒子.

如果堆分配不可用......那么您可能需要查看PinMut或以其他方式借用该结构.借来的东西不能动摇.