我有一个库“业务逻辑”板条箱,我希望能够为其编写多个二进制板条箱“前端”或“平台层”。这些平台层倾向于使用调用平台API的库,这往往意味着较长的编译时间。我希望能够在业务逻辑板条箱上进行迭代,而无需重新编译平台层。但是,我希望能够针对每个平台将项目编译为一个二进制文件,并且如果不需要的话,我不希望弄乱共享的目标文件/ DLL。
我有一种方法可以使用fn
指针和static mut
,但是有this rust-lang/rust
issue about potentially removing it,所以我想知道是否有办法获得结果想要而不使用它。
作为参考,我的工作方式如下:
use platform_types::{Input, Output};
fn update_and_render(input: Input) -> Output {
static mut STATE: logic::State = logic::new();
let state: &mut logic::State = unsafe { &mut STATE };
logic::update_and_render(state, input)
}
fn main() {
platform_layer::run(update_and_render);
}
上述代码位于主包装箱中,logic
是业务逻辑包装箱,platform_layer
是平台层包装箱,platform_types
包含其他三个包装箱中的通用类型
我尝试将RefCell
与try_borrow_mut
一起使用,但收到错误std::cell::RefCell<State> cannot be shared between threads safely
,并提到Sync
未实现std::cell::RefCell<State>
且错误未消除如果我尝试通过实验实现State
的同步功能,则无需执行。然后,我尝试了Mutex
,但据我所知我不能将其放在static
中。
编辑:如果有所作为,我实际上并不希望需要从多个线程中调用函数指针,尽管我知道隐式地分发可以实现这一点。如果我曾经(偶然地?)确实从多个线程中调用了函数指针,那么失败的debug_assert!
或类似方法显然比UB更可取。
答案 0 :(得分:2)
您可以将state
移至main()
fn main() {
let mut state = logic::new();
platform_layer::run(move |input| logic::update_and_render(&mut state, input));
}
答案 1 :(得分:2)
您可以使用静态互斥锁,并在需要时获取本地可变引用:
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;
fn update_and_render(input: Input) -> Output {
lazy_static! {
static ref STATE_MUTEX: Mutex<logic::State> = Mutex::new(logic::new());
}
let mut state = STATE_MUTEX.lock().unwrap();
logic::update_and_render(state, input)
}
这是快速,安全的,并且可以从多个线程进行访问。