我试图将一些多态类拆分为一个 dll 文件。然后我得到一个未注册的多态类型的异常。问题似乎是代码创建了两个用于查找多态对象的映射实例(由模板类 grain::detail::StaticObject 保留)。如果我将 CEREAL_REGISTER_TYPE 放入进行序列化的项目中,那么一切正常。
所以我想知道是否有人知道是否可以做一些技巧来在 dll 文件中进行注册?
是否可以强制程序使用谷物::detail::StaticObject 类的相同实例?
问问题
167 次
2 回答
0
从谷物 v1.1.0开始,可以通过将多态类型注册移动到头文件来解决此问题,这将确保包括该头文件的任何翻译单元正确初始化其静态对象。请记住在调用注册宏之前包含您希望绑定到的档案。
[主要谷物文档] 站点 ( http://uscilab.github.io/cereal/polymorphism.html )上提供了更多信息,该站点也已针对 1.1 进行了更新。
于 2015-01-19T21:38:46.463 回答
0
通过在我的 DLL 依赖链底部的 DLL 中的 hpp 中添加以下语句,我设法用 1.3.0(也应该与 1.1 一起使用)解决了这个问题。我们称之为core.dll。在该 DLL 中,我将有一个名为 config.hpp 的文件,其中包含以下传统宏。CMake 将在为 core.dll 生成构建脚本时定义 core_EXPORTS
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
# if defined(core_EXPORTS)
# define CORE_DECL __declspec(dllexport)
# else
# define CORE_DECL __declspec(dllimport)
# endif
#endif
然后在 core.dll 的另一个 export.hpp 我有以下
namespace cereal {
namespace detail {
// these declspecs will ensure that the polymorphic loader/saver registrations will
// all happen against the binding maps in core.dll
template class CORE_DECL StaticObject<InputBindingMap<PortableBinaryInputArchive>>;
template class CORE_DECL StaticObject<InputBindingMap<JSONInputArchive>>;
template class CORE_DECL StaticObject<OutputBindingMap<PortableBinaryOutputArchive>>;
template class CORE_DECL StaticObject<OutputBindingMap<JSONOutputArchive>>;
// add similar statements for other archive types as needed
template class CORE_DECL StaticObject<Versions>;
} // namespace detail
} // namespace cereal
其他 dll 项目中的所有其他 cpp 文件将 #include core/export.hpp 从而告诉链接器使用 core.dll 中的谷物静态对象。如果您调试 InputBindingCreator 构造函数,您会注意到现在每个类都在同一个绑定映射中注册。
我认为将以上内容添加到有关此主题的谷物文档中会很有用。
于 2019-12-19T16:05:12.953 回答