序列化具有嵌入类的boost类,但仅对包装器中的信息进行序列化

Posted

技术标签:

【中文标题】序列化具有嵌入类的boost类,但仅对包装器中的信息进行序列化【英文标题】:Serializing a class with boost that has embedded classes, but only the information in the wrapper is serialized 【发布时间】:2014-09-23 12:46:20 【问题描述】:

我正在使用 Boost 1.47.0 来序列化一些用于网络传输的类。我对图书馆不是很熟悉,但我已经阅读了很多文档,现在在两三天没有让它工作之后,我需要一些帮助。

我有课

class NetworkMessage

    public:
        NetworkMessage();
        void addPlayer(Player* player);
        std::string serializeToString();
        Player getPlayer();
        virtual ~NetworkMessage();
    protected:
    private:
        Player players;

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        
            ar & players;
        
;

此时我已将其限制为仅在消息中发送一个玩家的信息,并且工作正常,但我的播放器中包含另一个类,即相机。我的播放器类中的所有本机 C++ 成员都正确序列化。但是,当我反序列化它时,我的玩家相机的所有信息都会丢失。但其他信息被保留并有效。我已经调试了我的网络传输,并且收到的消息中包含所有序列化信息。

我不确定我是否误解了图书馆的工作原理,但伸出援助之手会非常有用,甚至只是一些建议,可以指导我正确地解决可能出现的问题。

顺便说一句,我使用的是 boost 提供的标准 serialize 方法。

class Player

    public:
        Player();
        Player(float _x, float _y, float _z, std::string _name);
        void setCamera(Camera camera);
        vec3 getLocation();
        std::string getName();
        Camera getCamera();
        virtual ~Player();
    protected:
    private:
        float x;
        float y;
        float z;
        std::string name;
        Camera playerCam;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    
        ar & x;
        ar & y;
        ar & z;
        ar & name;
        ar & playerCam;
    

;

编辑:添加了相机类。

class Camera

    public:
        Camera();
        Camera(vec3 r, vec3 u, vec3 d);
        Camera& operator=(Camera rhs);
        void rotateCamera(int xDelta, int yDelta, int xMid, int yMid);
        void setKey(unsigned char key, bool state);
        void updateCamera();
        void print();
        void printVec(vec3 vectr);
        mat4 getViewMatrix();
        vec3 getEye();

    private:

        mat4 view;
        vec3 r;
        vec3 u;
        vec3 d;
        vec3 direction;
        bool keyStates[256];

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        
            ar &r;
            ar &u;
            ar &d;
            ar &direction;
            ar &keyStates;
            ar &view;
        
;

我还添加了用于序列化 GLM 的向量和矩阵的代码。

namespace boost

    namespace serialization
    
        template<class Archive>
        void serialize(Archive & ar, glm::detail::tmat4x4<float> transform, const unsigned int version)
        
            ar & transform[0];
            ar & transform[1];
            ar & transform[2];
            ar & transform[3];
        

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec3<float> vec, const unsigned int version)
        
            ar & vec.x;
            ar & vec.y;
            ar & vec.z;
        

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec4<float> vec, const unsigned int version)
        
            ar & vec.x;
            ar & vec.y;
            ar & vec.z;
            ar & vec.w;
        

        template<class Archive>
        void serialize(Archive & ar, glm::detail::tvec2<float> vec, const unsigned int version)
        
            ar & vec.x;
            ar & vec.y;
        
    

【问题讨论】:

【参考方案1】:

好的,所以我发现了问题,我现在正在踢自己。

在我的 glm 相关好东西的序列化中,我需要将它们作为参考传递。我没有这样做。所以基本上我有:

template<class Archive>
void serialize(Archive & ar, glm::detail::tvec3<glm::mediump_float> vec, const unsigned int version)

    ar & boost::serialization::make_nvp("x", vec.x);
    ar & boost::serialization::make_nvp("y", vec.y);
    ar & boost::serialization::make_nvp("z", vec.z);

但它应该是:

template<class Archive>
void serialize(Archive & ar, glm::detail::tvec3<glm::mediump_float>& vec, const unsigned int version)

    ar & boost::serialization::make_nvp("x", vec.x);
    ar & boost::serialization::make_nvp("y", vec.y);
    ar & boost::serialization::make_nvp("z", vec.z);

感谢所有试图帮助我的人:)

【讨论】:

现在我也在踢自己,因为我在 SO 上已经 seen this particular pitfall before。 +1

以上是关于序列化具有嵌入类的boost类,但仅对包装器中的信息进行序列化的主要内容,如果未能解决你的问题,请参考以下文章

提升前向声明类的序列化

Boost Python 包装的虚拟类子返回错误:与 C++ 签名不匹配

Boost.Python 如何拥有 C++ 类?

需要引导程序类“嵌入式响应项目”来使用织物画布元素

提升引用成员抽象类的序列化

NonSerialized 属性创建错误