繁体   English   中英

提升:序列化/反序列化通过ZeroMQ拉套接字传递的自定义C ++对象

[英]Boost: Serializing/De-serializing a custom C++ object passed over ZeroMQ pull socket

描述:

我有一个名为GenericMessage的C ++类, 它只包含一个id和数据作为其成员(参见下面的代码片段1 - GenericMessage.hxx)。 我的目的是序列化这个类的一个实例,并通过一个实现推送模式的ZeroMQ套接字发送它。

序列化和发送任务已在类ZMQHandler中实现(请参阅sendToBE函数),该函数放在头文件名ZMQHandler.hxx中,如下面的代码片段2所示。 此类由TestFE.cxx实例化,如下面的第3个代码片段所示。

GenericMessage实例的接收和反序列化在TestBE.cxx中实现,可在下面的第4个代码片段中找到。 我的意图是通过ZMQ套接字(即拉套接字)接收GenericMessage实例,对其进行反序列化,然后打印其成员。

问题:

问题是当我编译TestBE.cxx时,我遇到了许多涉及模板函数的编译错误。 考虑到TestBE.cxx中的代码,有人能告诉我在第四个代码片段中标有注释的反序列化部分中我缺少什么吗? 我是一个相对新的C ++程序员,并想知道我应该如何解释这些模板函数相关的编译错误,这些错误已在本文的底部列出(即最终的片段)。 编译错误发生的第18行标记在第4个代码片段中。 谢谢。

代码SNIPPET 1(GenericMessage.hxx)

#include <iostream>
#include <string>
#include <sstream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

template <class T>
class GenericMessage {
public:
      GenericMessage(): 
      beId(-1), data(NULL)
      {}

      GenericMessage(int id, T msg): beId(id), data(msg)
      {}

     ~GenericMessage(){}

     T getData()
     {
       return data;
     }


     std::string toString()
     {
        std::ostringstream ss;
        ss << getBeId();
        std::string ret =  ss.str();

        return ret;
      }

      void setBeId(int id)
      {
        beId = id;
      }

      int getBeId()
      {
        return beId;
      }


      private:
            friend class boost::serialization::access;

            int beId;
            T data;

            template <class Archieve>
            void serialize(Archieve & ar, const unsigned int version)
            {
               ar & beId;
               ar & data;
            }

 };

代码SNIPPET 2(ZMQHandler.hxx)

 #include "zmq.hpp"
 #include "GenericMessage.hxx"
 #include <pthread.h>
 #include <unistd.h>
 #include <cassert>

template <class A>
class ZmqHandler {
public:

       ZmqHandler():
   mContext(1),
   mOutbHandlerSocket(mContext, ZMQ_PUSH)
       {    
            mOutbHandlerSocket.bind ("tcp://*:5555");       
       }

       ~ZmqHandler() {}

        void sendToBE(GenericMessage<A> &theMsg)
        {
           std::stringstream ss(std::ios_base::binary| std::ios_base::out|  std::ios_base::in);
           boost::archive::binary_oarchive oa(ss, boost::archive::no_header);
           oa << theMsg;

           zmq::message_t msgToSend(sizeof(ss));

           memcpy(msgToSend.data(), ss.str().data(), ss.str().length());
           if(memcmp(msgToSend.data(), ss.str().data(), ss.str().length()) != 0)
           {
               printf("memcpy error\n");
           }

           mOutbHandlerSocket.send(msgToSend);
           std::cout << "SENT request: [" << theMsg.toString() << "]" << std::endl;
}   

    private:  
          zmq::context_t mContext;
          zmq::socket_t mOutbHandlerSocket;         
};

代码SNIPPET 3(TestFE.cxx)

 #include "ZmqHandler.hxx"

 int main ()
 {
   ZmqHandler<std::string> zmqHandler;
   int counter = 1;

   while(1)
   {  
     std::string data = "Hello there!\0";
     GenericMessage<std::string> msg(counter, data);
     zmqHandler.sendToBE(msg);
     counter++;
     sleep(1);
    }

    return 0;
 }     

CODE SNIPPET 4(TestBE.cxx)

 #include "zmq.hpp"
 #include "GenericMessage.hxx"
 #include <fstream>

 int main ()
 {
    //  Prepare our context and socket
    zmq::context_t context (1);
    zmq::socket_t socket (context, ZMQ_PULL);

   std::cout << "Connecting to FE..." << std::endl;
   socket.connect ("tcp://localhost:5555");

   while(1){
       zmq::message_t reply;
       socket.recv (&reply);

       /* !!!!!!! LINE 18 starts HERE !!!!!!! */
       std::stringstream is(reply.data(), std::ios_base::binary| std::ios_base::out| std::ios_base::in);
       boost::archive::binary_iarchive ia(is, boost::archive::no_header);

       GenericMessage<std::string> msg;
       ia >> msg;

       std::cout << "RECEIVED: " << msg.toString() << std::endl;
       std::cout << "DATA: " << ((std::string)msg.getData())  << std::endl;
    }

     return 0;
 }

TestBE.cxx的编译输出

 g++ -g -c TestBE.cxx GenericMessage.hxx
 TestBE.cxx: In function ‘int main()’:
 TestBE.cxx:18:104: error: invalid user-defined conversion from ‘void*’ to ‘const  __string_type& {aka const std::basic_string<char>&}’ [-fpermissive]
       In file included from /usr/include/c++/4.7/string:55:0,
             from /usr/include/c++/4.7/bits/locale_classes.h:42,
             from /usr/include/c++/4.7/bits/ios_base.h:43,
             from /usr/include/c++/4.7/ios:43,
             from /usr/include/c++/4.7/ostream:40,
             from /usr/include/c++/4.7/iostream:40,
             from GenericMessage.hxx:1,
             from TestBE.cxx:2:
  /usr/include/c++/4.7/bits/basic_string.tcc:214:5: note: candidate is:     std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&)  [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near  match>
  /usr/include/c++/4.7/bits/basic_string.tcc:214:5: note:   no known conversion for argument 1 from ‘void*’ to ‘const char*’
  TestBE.cxx:18:104: error: invalid conversion from ‘void*’ to ‘const char*’ [-fpermissive]
       In file included from /usr/include/c++/4.7/string:55:0,
             from /usr/include/c++/4.7/bits/locale_classes.h:42,
             from /usr/include/c++/4.7/bits/ios_base.h:43,
             from /usr/include/c++/4.7/ios:43,
             from /usr/include/c++/4.7/ostream:40,
             from /usr/include/c++/4.7/iostream:40,
             from GenericMessage.hxx:1,
             from TestBE.cxx:2:
       /usr/include/c++/4.7/bits/basic_string.tcc:214:5: error:   initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-fpermissive]
       make: *** [TestBE.o] Error 1

我会说错误信息非常清楚: stringstream构造函数需要输入openmodestd::string ,并且你传递了一个void*类型的参数( reply.data()的返回值)。

您可以将收到的消息转储到二进制文件中,但您仍需要进行一些转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM