这个问题在这里已有答案:
我有一个库“业务逻辑”箱我希望能够写出多个二进制包“前端”或“平台层”。这些平台层倾向于使用调用平台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更好。
您可以使用静态互斥锁,并在需要时获取本地可变引用:
#[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)
}
这是快速,安全的,并且可以从多个线程进行访问。
你可以将state
移动到main()
fn main() {
let mut state = logic::new();
platform_layer::run(move |input| logic::update_and_render(&mut state, input));
}