我可以避免在没有`static mut`的情况下重新编译我的平台层吗? [重复]

问题描述 投票:1回答:2

我有一个库“业务逻辑”箱我希望能够写出多个二进制包“前端”或“平台层”。这些平台层倾向于使用调用平台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包含其他三个包之间的常见类型。

我尝试使用RefCelltry_borrow_mut我得到了错误std::cell::RefCell<State> cannot be shared between threads safely并提到Sync没有为std::cell::RefCell<State>实现,如果我尝试实验同步State错误没有消失。然后我尝试了Mutex,但据我所知,我不能把它放在static

编辑:如果它有所作为,我实际上不希望需要从多个线程调用函数指针,虽然我知道隐含地交出一个允许。如果我(不小心?)从多个线程调用函数指针,那么失败的debug_assert!或类似的东西显然比UB更好。

static rust
2个回答
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)
}

这是快速,安全的,并且可以从多个线程进行访问。


2
投票

你可以将state移动到main()

fn main() {
    let mut state = logic::new();
    platform_layer::run(move |input| logic::update_and_render(&mut state, input));
}
© www.soinside.com 2019 - 2024. All rights reserved.