gpt4 book ai didi

rust - 动态加载的 crate 的一致 TypeId

转载 作者:行者123 更新时间:2023-11-29 08:00:48 26 4
gpt4 key购买 nike

我有一个插件系统,我将 &dyn Any 传递给动态加载的 rust 函数,但是向下转换引用失败,因为 TypeId 不同(对于同一类型) ,尽管我将 rustflags = ["-Cmetadata=12345678"] 添加到两个 crate 的 cargo 配置中。此外,似乎只有来自外部 crate 的类型受到影响(我尝试了 () 并且它在两个 crate 中产生了相同的 TypeId )。我目前正在转换原始指针 (unsafe { &*(v as *const dyn Any as *const Type) }) 来解决这个问题,但我更喜欢没有不安全代码的解决方案。

例如下面的代码:

println!("CRATE 1: TypeId of `()`: `{:?}`, TypeId of `toml::Value`: `{:?}`",
TypeId::of::<()>(), TypeId::of::<toml::Value>());

产生这个输出:

CRATE 1: TypeId of `()`: `TypeId { t: 7549865886324542212 }`, TypeId of `toml::Value`: `TypeId { t: 9270396907601429078 }`
CRATE 2: TypeId of `()`: `TypeId { t: 7549865886324542212 }`, TypeId of `toml::Value`: `TypeId { t: 5704635987193303200 }`

编辑:这似乎不是不同依赖版本的问题,因为 crate 2(动态加载)依赖于 crate 3(也是动态加载)并且问题仍然存在,尽管 crate 2 和 crate 3 都是本地的依赖项(因此只有一个版本)。 crate 1 是顺便说一句。装载 crate 2 和 3 的 crate 。

编辑:我从所有 3 个 crate 中删除了 -Cmetadata 选项,现在我为 toml::Value 获得了相同的 TypeId,但是 TypeId 我想在箱子 2 中向下转换的箱子 1 中的类型仍然不同。

最佳答案

经过一些测试后,我发现 TypeId 不同,因为加载程序 crate(crate 1)在其他 2 个 crate 中用作库,但作为二进制文件执行。

为了解决这个问题,我将我想在加载的箱子中使用的所有箱子 1 的类型提取到一个新的箱子中,并将其添加到每个箱子的依赖项中。这个新的 crate 只用作库而不是二进制文件,因此 TypeId 应该是一致的。

为了让它工作我必须做的一切的总结:

  • 对所有 crate 使用相同的工具链版本
  • 在所有 crate 中使用相同的依赖版本
  • 不要使用-Cmetadata,这不再有效,实际上有相反的效果
  • 将加载器 crate 和加载的 crate 中使用的所有类型提取到一个新的 crate 中,并将其添加到所有 crate 的依赖项中
  • 每当您更改此“通用类型 crate”中的内容时,您必须重新编译所有其他 crate,因此 TypeIdS 是最新的

如果你仍然有问题,你可以回退到不安全的使用rust (例如 unsafe { &*(value as *const dyn Any as *const Type) })。请注意,根本没有检查,因此如果类型不匹配,您可能会遇到段错误。

特别感谢@trentcl 为我指明了正确的方向。

关于rust - 动态加载的 crate 的一致 TypeId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57536484/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com