如何存储引用而不必处理生命周期?

2023-11-30

正如建议的the dynamic_reload板条箱的例子, 我收集了Symbols 而不是每次都提取它们,但是Symbol需要一生。使用生命周期会更改方法签名并破坏与方法的兼容性DynamicReload::update.

这是一个有效的解决方法吗std::mem::transmute改变Symbol的一生到'static?

extern crate dynamic_reload;

use dynamic_reload::{DynamicReload, Lib, Symbol, Search, PlatformName, UpdateState};
use std::sync::Arc;
use std::time::Duration;
use std::thread;
use std::mem::transmute;

struct Plugins {
    plugins: Vec<(Arc<Lib>, Arc<Symbol<'static, extern "C" fn() -> i32>>)>,
}

impl Plugins {
    fn add_plugin(&mut self, plugin: &Arc<Lib>) {
        match unsafe { plugin.lib.get(b"shared_fun\0") } {
            Ok(temp) => {
                let f: Symbol<extern "C" fn() -> i32> = temp;
                self.plugins.push((plugin.clone(), Arc::new(unsafe { transmute(f) })));
            },
            Err(e) => println!("Failed to load symbol: {:?}", e),
        }
    }

    fn unload_plugins(&mut self, lib: &Arc<Lib>) {
        for i in (0..self.plugins.len()).rev() {
            if &self.plugins[i].0 == lib {
                self.plugins.swap_remove(i);
            }
        }
    }

    fn reload_plugin(&mut self, lib: &Arc<Lib>) {
        Self::add_plugin(self, lib);
    }

    // called when a lib needs to be reloaded.
    fn reload_callback(&mut self, state: UpdateState, lib: Option<&Arc<Lib>>) {
        match state {
            UpdateState::Before => Self::unload_plugins(self, lib.unwrap()),
            UpdateState::After => Self::reload_plugin(self, lib.unwrap()),
            UpdateState::ReloadFailed(_) => println!("Failed to reload"),
        }
    }
}

fn main() {
    let mut plugs = Plugins { plugins: Vec::new() };

    // Setup the reload handler. A temporary directory will be created inside the target/debug
    // where plugins will be loaded from. That is because on some OS:es loading a shared lib
    // will lock the file so we can't overwrite it so this works around that issue.
    let mut reload_handler = DynamicReload::new(Some(vec!["target/debug"]),
                                                Some("target/debug"),
                                                Search::Default);

    // test_shared is generated in build.rs
    match reload_handler.add_library("test_shared", PlatformName::Yes) {
        Ok(lib) => plugs.add_plugin(&lib),
        Err(e) => {
            println!("Unable to load dynamic lib, err {:?}", e);
            return;
        }
    }

    //
    // While this is running (printing a number) change return value in file src/test_shared.rs
    // build the project with cargo build and notice that this code will now return the new value
    //
    loop {
        reload_handler.update(Plugins::reload_callback, &mut plugs);

        if plugs.plugins.len() > 0 {
            let fun = &plugs.plugins[0].1;
            println!("Value {}", fun());
        }

        // Wait for 0.5 sec
        thread::sleep(Duration::from_millis(500));
    }
}

我还得保留Arc<Lib>在向量内部,因为Symbol不执行PartialEq.


如何存储引用而不必处理生命周期?

98%的情况下答案是:你不。生命周期是使用 Rust 的最大原因之一。一生强制执行,在编译时,您的参考文献将始终引用有效的内容。如果您希望“忽略”生命周期,那么 Rust 可能不是实现特定设计的最佳语言。您可能需要选择不同的语言或设计。

这是一个有效的解决方法吗std::mem::transmute改变Symbol的一生到'static?

transmute是大锤子,适合各种好的和坏的想法和实现。我鼓励不要直接使用它,而是将它包装在一个抽象层中,以某种方式帮助您实施适当的限制,使特定的转换正确。

如果您选择使用transmute,你假设全部责任编译器以前有的。您需要确保参考文献是always有效,否则您将调用未定义的行为,并且您的程序可以执行任意数量的非常糟糕的事情。


对于您的具体情况,您may能够使用租赁箱将“库”和“对库的引用”保留在一个隐藏了生命周期的结构中Symbols。事实上,租赁用途库加载作为激励性示例,libloading 为dynamic_reload 提供了动力。看为什么我不能在同一结构中存储值和对该值的引用?了解更多细节和陷阱。

我对这会起作用并不乐观,因为DynamicReload::update需要一个&mut self。在该方法调用期间,它可以轻松地使所有现有引用无效。

也可以看看:

  • 为什么我不能在同一结构中存储值和对该值的引用?
  • 如何避免将具体结构更改为通用结构带来的连锁反应?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何存储引用而不必处理生命周期? 的相关文章

随机推荐

  • 遍历 4 个数字的组合

    我需要一个代码来运行 4 个数字的可能组合 例如 1234 将产生 1234 1243 1324 等的 24 种组合 但不做 1 12 123 ect 我希望它只有 4 个数字长度组合 只是改变顺序 一个很长的选择是 import rand
  • 张量流可以扫描并只保留最终结果吗?

    以下代码计算数组的总和tf scan 张量流会分配一个 6 元素数组来保存六个部分和吗 或者 tensorflow 足够聪明 只分配一个 1 元素数组来保存部分和 如何确定 import tensorflow as tf import nu
  • 未捕获的类型错误:firebase.auth 不是函数

    我尝试使用 firebase 电子邮件和密码 构建一个身份验证应用程序 但我对 firebase 方法有问题 当我致电 firebase auth 时 他们说 这不是一个函数 是因为我的项目和 firebase SDK 没有链接吗 您有什么
  • 多边形顶点 - 顺时针或逆时针

    我发现了这个链接http www mathopenref com coordpolygonarea2 html 它解释了如何计算多边形的面积 并有助于识别我们输入的多边形顶点是顺时针还是逆时针 如果面积值为 ve 则为顺时针方向 如果为 n
  • PHP 登录本机控制台 Firefox Developer

    与 Firebug 相比 我更喜欢 Firefox 开发者检查器 但是可以在原生 JS 控制台中显示 PHP 日志吗 谢谢 我刚刚安装了 Chrome Logger github website with Chrome PHP由于 Fire
  • 测试具有 CSRF 保护的 scala Play (2.2.1) 控制器

    我在测试使用 Play 的 CSRF 保护的控制器时遇到了一些问题 为了演示这一点 我创建了一个非常简单的 Play 应用程序 以最小程度地展示该问题 https github com adamnfish csrftest 完整的详细信息位
  • 无法满足从 com.lmax.disruptor 3.2.0 到包 sun.misc 0.0.0 的依赖关系

    我正在开发一个 eclipse 插件 需要 com lmax disruptor 它导入 sun misc 我的 p2 存储库中有这个 但是当我 Maven 构建我的插件时 我收到此错误 无法满足从 com lmax disruptor 3
  • 如何在闭包中调用函数

    在模特的课堂上Location 我得到当前城市的名称 var currentLatitude Double var currentLongitude Double var currentLocation String var current
  • Dynamic_cast 来自由 lt_dlopen(libtool) 加载的共享库的接口不起作用

    这是关于我的程序中的插件功能 我需要插件中的 C 类 和对象 可以由主模块通过接口使用 接口继承是这样的 typedef struct rwd plugin root t RWD PLUGIN ROOT T struct RWD PLUGI
  • C# 使用具有泛型属性的反射

    我有一个使用通用属性的类 例如 class Person public MyGenericProperty
  • JasperReports 字体

    我需要以 PDF 格式导出日本报告 报告字体必须是 Tahoma 所以我将报告字体设置为 Tahoma 最初它抛出像 tahoma 不适用于 JVM 我已将 tahoma ttf 作为 jar 放在类路径中 之后 当我执行时 对于 Taho
  • 从批处理脚本行“如果存在[文件](...

    相关代码如下所示 cd d dp0 if exist filename txt echo date time text gt gt filename2 txt echo echo text echo text echo text text
  • 在 R 中给定特定概率值生成随机数(0 和 1)

    我在 R 中找不到这个问题的答案 我想生成 0 到 1 的 RandomSample 的随机样本 对于每个样本 我希望有一个特定数量的值 numval 它是从向量 Prob 的长度导出的 Prob 给出的是每个点为 0 或 1 的概率值 因
  • spring boot mongodb连接错误

    我尝试将 Spring Boot 应用程序连接到 mongodb 但驱动程序类出现连接错误 这是代码的一部分 我的 pom xml
  • 如何实现 @JsonUnwrap 的 Gson 等效项

    我知道 Gson 没有类似的功能 但是有没有办法添加对展开 Json 字段的支持 JsonUnwrap does 目标是允许这样的结构 public class Person public int age public Name name
  • 基于动作的对象事件有时会丢失

    假设已知某个 PS 代码中引用的对象在以下时间段内触发了 100 个事件 Register ObjectEvent and Unregister Event 期望主机代码接收 100 个事件 然而 有时它收到的信息少于 100 个 很多时候
  • 参考 R 中的相关行

    我知道这个答案一定就在那里 但我不知道如何表达这个问题 我想计算 data frame 中值之间的差异 由此 f lt data frame year c 2004 2005 2006 2007 value c 8565 8745 8985
  • 通过 Javascript 杀死 Java Applet

    我在一家开发公司工作 正在对 Web 应用程序进行重大重新设计 每次单击后都会重新加载所有内容 以广泛使用 Javascript 因此它实际上感觉就像一个真正的 Web 应用程序 其中一项功能是使用基于 Web 的 Painter 想想 W
  • WCF:无法为 SSL/TLS 安全通道建立信任关系,权限错误

    我有一个客户端站点 当单击按钮时它会调用 wcf Web 服务 客户端站点是 http 而 Web 服务的 url 是 https 并且需要证书 我正在使用有效的签名私钥证书 在我的本地主机上一切正常 但是 在部署到运行 iis 6 的 W
  • 如何存储引用而不必处理生命周期?

    正如建议的the dynamic reload板条箱的例子 我收集了Symbols 而不是每次都提取它们 但是Symbol需要一生 使用生命周期会更改方法签名并破坏与方法的兼容性DynamicReload update 这是一个有效的解决方