Caching 在静态变量中缓存外部加载的数据

Caching 在静态变量中缓存外部加载的数据,caching,static,rust,ffi,Caching,Static,Rust,Ffi,我想从一个文件中加载数据,然后将这些数据(包括相当大的数组)缓存在一个静态变量中。这显然不是最好的方法,但是: 我正在编写一个由C(++)程序调用的Rust库,目前还并没有任何对象能够实时调用Rust函数。使用static可以避免我不得不破解C代码 程序内部不同时执行任何操作,因此同步不是问题 如何在生锈的情况下实现这一点 我发现它解决了类似的问题,但只适用于不需要外部资源的代码(即理论上可以在编译时进行评估的项)。您不能在程序启动时进行初始化,但可以在第一次方法调用时进行初始化。所有后续调用都

我想从一个文件中加载数据,然后将这些数据(包括相当大的数组)缓存在一个静态变量中。这显然不是最好的方法,但是:

  • 我正在编写一个由C(++)程序调用的Rust库,目前还并没有任何对象能够实时调用Rust函数。使用static可以避免我不得不破解C代码
  • 程序内部不同时执行任何操作,因此同步不是问题
  • 如何在生锈的情况下实现这一点


    我发现它解决了类似的问题,但只适用于不需要外部资源的代码(即理论上可以在编译时进行评估的项)。

    您不能在程序启动时进行初始化,但可以在第一次方法调用时进行初始化。所有后续调用都将访问缓存的值,而不是重新计算您的值

    因为rust禁止在静态变量中使用析构函数,所以您需要自己进行清理管理。从逻辑上讲,这意味着您需要不安全的代码来破坏rust的安全系统。下面的示例使用
    静态mut
    变量来缓存堆分配的对象(本例中为
    i32
    )。 cacheload函数的工作方式类似于单例

    完成后,请记住从c调用cachefree()

    use std::{ptr, mem};
    
    static mut cache: *const i32 = 0 as *const i32;
    
    unsafe fn cacheload() -> i32 {
        if cache == ptr::null() {
            // do an expensive operation here
            cache = mem::transmute(Box::new(42));
        }
        return *cache;
    }
    
    unsafe fn cachefree() {
        if cache != ptr::null() {
            let temp: Box<i32> = mem::transmute(cache);
            cache = ptr::null();
            drop(temp);
        }
    }
    
    fn main() {
        let x;
        unsafe {
            x = cacheload();
            cachefree();
        }
        println!("{}" , x);
    }
    
    使用std:{ptr,mem};
    静态多缓存:*常量i32=0作为*常量i32;
    不安全的fn cacheload()->i32{
    如果缓存==ptr::null(){
    //在这里做昂贵的手术
    cache=mem::transmute(Box::new(42));
    }
    返回*缓存;
    }
    不安全的fn cachefree(){
    如果缓存!=ptr::null(){
    让temp:Box=mem::transmute(缓存);
    cache=ptr::null();
    下降(温度);
    }
    }
    fn main(){
    设x;
    不安全{
    x=缓存加载();
    无缓存();
    }
    println!(“{}”,x);
    }
    
    我想,除了程序退出时内存泄漏并不重要(在大多数现代操作系统上)。因此,也许这在不扩展C API的情况下也能起作用。您是否被介绍过?使用一次将打破以任意顺序和数量重复使用cachefree和cacheload的可能性,但一般来说,这是一种更好的初始化一次的方法。
    一次
    如果我不必多次修改缓存,就可以工作。如果你希望这是线程安全的,你可能应该使用互斥锁;现在,您可以使用
    Box::into_raw()
    将方框转换为
    *mut i32