wupeter1 发表于 2009-8-9 12:00:09

求教:关于复杂消息序列化和反序列化问题

内容比较多请大家耐心帮我看一下

范围查询消息涉及好多类
classAFX_EXT_CLASSCMsgRect
: public CMsg
{
public:
        Envelope3D m_box3d;

        vector<string> m_vecVisibleFClass;

        CMsgRect();

        CMsgRect(Envelope3D box3d, vector<string> visibleFClass,int nType=0,void *pParam=NULL);
        ~CMsgRect();

};
class AFX_EXT_CLASS CMsg
        {
        public:
                MSG_TYPE msg_Type;   // MSG_TYPE为枚举类型

                int nType;
                void* pParam;

                CMsg();
                CMsg(MSG_TYPE msg_Type, int nType = 0, void* pParam=NULL);
                virtual ~CMsg();

        };
class AFX_EXT_CLASSEnvelope3D
{
protected:
        Vertex3d m_VMin;
        Vertex3d m_VMax;
public:
                void SetMax(const Vertex3d& maxV)
        {
                m_VMax = maxV;
        }

        void SetMin(const Vertex3d& minV)
        {
                m_VMin = minV;
        }
};

class AFX_EXT_CLASS Vertex3d
{
public:
        double x;
        double y;
        double z;
};

class CMsgRect 为范围查询类,其中涉及Envelope3D类 和Vertex3d

/// @brief 消息结构体
   struct TPack
                {
#pragma pack(push)
#pragma pack(1)
                        unsigned int seq;
                        unsigned long int len;
                        char Msg;
#pragma pack(pop)
                };

序列化过程及发送:
   Vertex3d min_vertex,max_vertex;
   min_vertex.x =100.0;
   min_vertex.y =100.0;
   min_vertex.z =100.0;

   max_vertex.x =105.0;
   max_vertex.y =105.0;
   max_vertex.z =105.0;
   
   AABBox box;
   box.SetMax(max_vertex);
   box.SetMin(min_vertex);
   
   CMsgRect msg_rect;
   msg_rect.msg_Type = MSG_RECT;
   msg_rect.nType =1;
   msg_rect.pParam = NULL;
   msg_rect.m_vecVisibleFClass.push_back ("rect seek");
   msg_rect.m_box3d =box;
   
   int length=sizeof(unsigned int)+sizeof(unsigned long int);
   TPack MsgPack;
   MsgPack.seq=0;
       
   memcpy(MsgPack.Msg ,&msg_rect,sizeof(msg_rect));
   CMsgRect* rect = (CMsgRect*) MsgPack.Msg ;
   
   MsgPack.len =sizeof(msg_rect);
   length+=MsgPack.len;
   char temp;
   memcpy(temp,&MsgPack,length);
   client.send_request (temp,length); //发送

接收反序列化
char* ptr = msg->rd_ptr();
ACE_UINT32 ip = *(ACE_UINT32 *)ptr; ptr += sizeof(ACE_UINT32);
ACE_UINT16 port = *(ACE_UINT16 *)ptr; ptr += sizeof(ACE_UINT16);
TTcpPackHeader* header = (TTcpPackHeader *)ptr; ptr += TCP_PACK_HEADER_SIZE;

CMsgRect * rect = (CMsgRect *)ptr; 设置断点发现 rect 成员m_box3d、msg_Type、nType、pParam 都能正确接收,但是 m_vecVisibleFClass接收不到,把vector<string> m_vecVisibleFClass该为 string visible并赋值 也接收不到,string 类型的都接收不到,不知道怎么回事。求大家帮帮忙!!!

wupeter1 发表于 2009-8-9 16:07:29

都只是路过,不留下点什么啊

winston 发表于 2009-8-9 18:17:00

你的代码,有很大的问题呀。m_vecVisibleFClass是类,不能直接序列化,然后传到对方的。除非你做特别的处理。
要知道,网络只认识字符流呀。
我觉得你最核心的概念,还没搞清楚呢。

wupeter1 发表于 2009-8-10 09:27:42

关于string,其实就是浅拷贝和深拷贝的问题。通常的string,其内部都有一个包含数据的指针。如果进行内存拷贝时(如你调用的memcpy),没有进行深拷贝(没能拷贝数据指针所指向的内容,仅复制了指针),则拷贝是不完全的,这就是你所遇到的问题。简单的解决方法:
1.
显式暴露内部数据域,逐项进行复制。
2.
实现一个类型转换的操作符
重载,该方法可能会引起副作用。
3.
显示实现一个导出内部数据内容的方法,实现你所意图的内存拷贝。
4.
实现存储类(Storage),该方法代价比较高。
页: [1]
查看完整版本: 求教:关于复杂消息序列化和反序列化问题