我试图拆分一些多态类以序列化为dll文件。然后,我得到了未注册的多态类型的异常。问题似乎是该代码创建了用于查找多态对象的地图的两个实例(由模板类谷物:: detail :: StaticObject保留)。如果我将CEREAL_REGISTER_TYPE放入进行序列化的项目中,那么一切都很好。因此,我想知道是否有人知道是否有一些技巧可以在dll文件中进行注册?是否可以强制程序使用谷物:: detail :: StaticObject类的相同实例?
自cereal v1.1.0起,可以通过将多态类型注册移动到头文件来解决此问题,这将确保任何包含该头的转换单元都能正确初始化其StaticObject。只需记住在调用注册宏之前包含您要绑定的档案即可。
[谷物主要文档]站点上有更多可用信息[http://uscilab.github.io/cereal/polymorphism.html,该站点也已更新为1.1。
我设法通过在DLL依赖关系链底部的DLL中的hpp中添加以下语句,以1.3.0解决了这个问题(也应该与1.1一起工作)。我们称它为core.dll。在该DLL中,我将拥有一个名为config.hpp的文件,其中包含以下传统宏。当为core.dll生成构建脚本时,CMake将定义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中会很有用。