我试图将一些多态类拆分为序列化为dll文件。然后我得到未注册的多态类型的异常。问题似乎是代码创建了用于查找多态对象的地图的两个实例(由模板类grain :: detail :: StaticObject保留)。如果我将CEREAL_REGISTER_TYPE放入进行序列化的项目中,那么一切都很顺利 所以我想知道是否有人知道是否有可能做一些技巧,以便能够在dll文件中进行注册? 是否可以强制程序使用cereal :: detail :: StaticObject类的相同实例?
答案 0 :(得分:0)
从cereal v1.1.0开始,可以通过将多态类型注册移动到头文件来解决此问题,这将确保包含该头的任何转换单元正确初始化其StaticObject。只需记住在调用注册宏之前包含要绑定的存档。
[主要谷物文件]网站(http://uscilab.github.io/cereal/polymorphism.html)提供了更多信息,该网站也已更新为1.1。
答案 1 :(得分: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中使用谷物StaticObjects。如果调试InputBindingCreator构造器,您会注意到每个类现在都在同一绑定映射中注册。
我认为将以上内容添加到cereal documentation on this topic中会很有用。