Box <any> downcast在dylib模块中返回None

时间:2016-07-31 11:21:48

标签: rust

我使用dylib作为插件解决方案。当我调用函数register时(在下面的代码中,fun是我的项目名称):

let register = plugin.get::<unsafe extern fn(&mut fun::mem::Mem)>("register").unwrap();
unsafe {
    register(&mut mem);
}

在dylib的register函数中,mem.get_mut::<fun::router::Router>("router")返回None

但如果我在mem.get_mut::<fun::router::Router>("router")中使用main.rs。它会根据我的意愿返回Router

我测试更多并得到以下结果:

在dylib中:

  • mem.get_mut::<String>("test")效果很好。
  • mem.get_mut::<fun::Bob>("bob")返回None

main.rs

  • mem.get_mut::<String>("test")效果很好。
  • mem.get_mut::<fun::Bob>("bob")效果很好。

我的问题:

为什么downcast_mut会在dylib中返回None,如果在主模块中定义了向下转换的泛型类型?

mem struct:

#[derive(Debug)]
pub struct Mem {
    pub value: HashMap<String, Box<Any>>,
}

get_mut:

pub fn get_mut<T: Any>(&mut self, key: &str) -> Option<&mut T> {
    match self.value.get_mut(key) {
        Some(val) => {
            match val.downcast_mut::<T>() {
                Some(value) => Some(value),
                None => None,
            }
        }
        None => None,
    }
}

抱歉我的描述不好。

更新

TypeId测试结果:

# in dylib's function:
Router TypeId: TypeId { t: 10245301028242226491 }
String TypeId: TypeId { t: 2231836747111135853 }

# in `main.rs`'s function:
Router TypeId: TypeId { t: 11005875220745415326 }
String TypeId: TypeId { t: 2231836747111135853 }

TypeId不同。针对这个问题的任何解决方案?

1 个答案:

答案 0 :(得分:4)

如上所述,到目前为止(1.10),TypeId在包装箱或编辑中并不稳定。

@eddyb就在本周登陆了pull request,这使TypeId独特的横排箱成为您特定的用例。

重要的是要注意这种稳定性并不完整;例如,如果您阅读了注释,则会注意到TypeId如果编译器版本或包版本发生更改,则可能会更改。尽管如此,对于单个编译器和共享依赖项,它现在在重新编译时仍然是稳定的。

目前,您可以使用夜间编译器,也可以等到下一个包含此补丁的稳定版本(我认为是1.12或1.13)。