MSVC 的 Boost 序列化(bug?)问题,在几个库中有 vector<shared_ptr>
Boost serialization (bug?) issue with MSVC, with vector<shared_ptr> in several libraries
我们在 linux (gcc) 和 Windows 上的项目中都使用了 boost 序列化。
我们仅在 Windows(对于 Windows(7 和 10)和 MSVC 的 "every" 版本:Visual 2010 和 2015,即 MSVC++ 10.0 _MSC_VER == 1600 或 MSVC++ 14.0 _MSC_VER == 1900).
这里总结了问题,但我需要在后面给出更多细节:
当我序列化一个 class
- 有基数 class
- 并且有 ClassB 的 shared_ptr 的 2 个向量,具有相同的内容,并且 B 继承自相同的基 class
序列化有效,但反序列化无效 ("input stream error")。
是的,很奇怪:
- 如果我删除基础 class,它会起作用。
- 如果我内联基 class 的序列化代码(空函数),它就可以工作。
- 如果 2 个向量的内容不同,它就可以工作!!
如果我在ClassTest的序列化方法中注册ClassBase,它就可以工作。即:
// in ClassTest:
template <class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar.template register_type<ClassBase>();
...
}
一些细节
当它在 linux 上工作时,当它在存档中使用 ClassBase 类型注册时在 Windows 上工作时,我们有相同的 xml输出。
值得注意的是:
- boost_serialization 在 Windows 上是版本 17,在 linux 上是版本 9(我还没有尝试在 linux 上更新 boost)。
- 在 BaseClass xml 标签上,tracking_level="1",所以我们有 object_id.
而当它不起作用时(再一次:ClassTest的序列化可以,但不能反序列化"input stream error"):
- 主要区别在于ClassTest的序列化:ClassBase部分没有tracking_level.
- 但这不是唯一的原因,因为如果向量不同(相同的第一项和第三项在一个向量中),tracking_level ClassTest 部分中的 ClassBase 为“0”。
最后一件事,如果它能给你一些线索的话:当我们调试我们的应用程序时,我们注意到反序列化框架试图将一个 class 反序列化为另一个。
这让我觉得序列化框架对 classe 类型标识感到困惑。
这可能是dll链接的问题吗?全局静态共享存储?
我已经发布了 visual studio 解决方案 here。
非常感谢您的帮助。如果需要任何说明,我当然可以!
我 post 如果有人有同样的问题并且正在浏览这个论坛,我会在这里回答。
感谢 boost 开发人员(您可能会阅读 this issue),修复方法是将 ClassBase 标记为 track_always:
BOOST_CLASS_TRACKING(ClassBase, boost::serialization::track_always)
我们在 linux (gcc) 和 Windows 上的项目中都使用了 boost 序列化。 我们仅在 Windows(对于 Windows(7 和 10)和 MSVC 的 "every" 版本:Visual 2010 和 2015,即 MSVC++ 10.0 _MSC_VER == 1600 或 MSVC++ 14.0 _MSC_VER == 1900).
这里总结了问题,但我需要在后面给出更多细节: 当我序列化一个 class
- 有基数 class
- 并且有 ClassB 的 shared_ptr 的 2 个向量,具有相同的内容,并且 B 继承自相同的基 class
序列化有效,但反序列化无效 ("input stream error")。
是的,很奇怪:
- 如果我删除基础 class,它会起作用。
- 如果我内联基 class 的序列化代码(空函数),它就可以工作。
- 如果 2 个向量的内容不同,它就可以工作!!
如果我在ClassTest的序列化方法中注册ClassBase,它就可以工作。即:
// in ClassTest: template <class Archive> void serialize(Archive & ar, const unsigned int version) { ar.template register_type<ClassBase>(); ... }
一些细节
当它在 linux 上工作时,当它在存档中使用 ClassBase 类型注册时在 Windows 上工作时,我们有相同的 xml输出。
值得注意的是:
- boost_serialization 在 Windows 上是版本 17,在 linux 上是版本 9(我还没有尝试在 linux 上更新 boost)。
- 在 BaseClass xml 标签上,tracking_level="1",所以我们有 object_id.
而当它不起作用时(再一次:ClassTest的序列化可以,但不能反序列化"input stream error"):
- 主要区别在于ClassTest的序列化:ClassBase部分没有tracking_level.
- 但这不是唯一的原因,因为如果向量不同(相同的第一项和第三项在一个向量中),tracking_level ClassTest 部分中的 ClassBase 为“0”。
最后一件事,如果它能给你一些线索的话:当我们调试我们的应用程序时,我们注意到反序列化框架试图将一个 class 反序列化为另一个。
这让我觉得序列化框架对 classe 类型标识感到困惑。
这可能是dll链接的问题吗?全局静态共享存储?
我已经发布了 visual studio 解决方案 here。
非常感谢您的帮助。如果需要任何说明,我当然可以!
我 post 如果有人有同样的问题并且正在浏览这个论坛,我会在这里回答。 感谢 boost 开发人员(您可能会阅读 this issue),修复方法是将 ClassBase 标记为 track_always: BOOST_CLASS_TRACKING(ClassBase, boost::serialization::track_always)