升压:反序列化的自定义C ++对象越过ZeroMQ拉插座 [英] Boost: De-serializing a custom C++ object passed over ZeroMQ pull socket

查看:317
本文介绍了升压:反序列化的自定义C ++对象越过ZeroMQ拉插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里写的文字是我在<一个较早开辟了另一个线程的后续问题href=\"http://stackoverflow.com/questions/14480161/boost-serializing-de-serializing-a-custom-c-object-passed-over-zeromq-pull-so\">Boost:序列化/反序列化定制的C ++对象越过ZeroMQ拉插座。在前面的线程编译问题已经通过使用textarchive类型,而不是binaryarchive解决,但现在我遇到反序列化时,一个运行时的问题。我在这里重复先前的文本与新的问题陈述为您提供方便。我是比较新的C ++领域和AP preciate任何进一步的帮助。

说明:

我有一个C ++类名为 GenericMessage 它只是持有ID和数据作为其成员(见下文code段2 - GenericMessage.hxx)。我的目的是序列化这个类的一个实例,并通过它实现了推模式的ZeroMQ套接字发送。

序列化和发送任务已在实施的类ZMQHandler (见sendToBE功能),它放置在 code片段3 <显示一个头文件名ZMQHandler.hxx / STRONG>下面。这个类是通过实例化 TestFE.cxx 中显示的的4RD code段之下。

在GenericMessage实例的接收和反序列化的实施 TestBE.cxx 5 code段可用下面。我的目的是在ZMQ插座(即拔插座),反序列化,然后将其成员打印到标准输出接收GenericMessage实例。

问题陈述:

当我运行的接收器(即TestBE.cxx)我验证在这里,我可以从TestFE.cxx在ZMQ套接字传输数据TEstBE.cxx。然而,我在下面正好一号code片段所示,当我试图反序列化的TestBE.cxx在第28行中输入档案(见下文非常第五届code段例外,第28行已标)。

时有什么我在TestBE.cxx在code段5实现了这个反序列化的过程不见了?为什么你认为我得到这个例外?难道说我在ZMQHandler.cxx实现序列化过程中的缺失ST(code片段3 - 功能sendToBE)。提前致谢。

code SNIPPET 1 GDB输出和回溯

  $ GDB TestBE
GNU GDB(GDB)7.5的Ubuntu
.....
(GDB)R
 启动程序:/ TestBE
 [使用线程调试libthread_db所启用]
 使用主机libthread_db所图书馆/lib/i386-linux-gnu/libthread_db.so.1。
 [新主题0xb7c12b40(LWP 16644)]
 [新主题0xb7411b40(LWP 16645)]
 连接到FE ...

!!!!!!!!!!!!!!!!!!!!从这里开始!!!!!!!!!!!!!!!!!!!!!! !!!!!

  ** CHAR [22 ::系列化存档9 0 1 0
 0 1 12你好!]
 抛出的一个实例后终止所谓的性病:: logic_error
 什么():basic_string的:: _ S_construct空无效**

!!!!!!!!!!!!!!!!!!!!在这里结束!!!!!!!!!!!!!!!!!!!!!! !!!!!

 程序接收到的信号SIGABRT,中止。
 0xb7fdd424在__kernel_vsyscall()
 (GDB)BT
 #0 0xb7fdd424在__kernel_vsyscall()
 从/lib/i386-linux-gnu/libc.so.6#1 0xb7c7a1df在加薪()
 #2 0xb7c7d825在中止()从/lib/i386-linux-gnu/libc.so.6
 在__gnu_cxx#3 0xb7e608ad :: __ verbose_terminate_handler()()从/ usr / lib中/ i386- Linux的GNU /的libstdc ++。so.6
 #4 0xb7e5e4f3的? ()从/usr/lib/i386-linux-gnu/libstdc++.so.6
 #5 0xb7e5e52f中的std ::终止()()从/usr/lib/i386-linux-gnu/libstdc++.so.6
 从/usr/lib/i386-linux-gnu/libstdc++.so.6#6 0xb7e5e825在__cxa_rethrow()
 #7 0x0804c1d4在boost ::档案::详细:: pointer_iserializer&LT;提高::档案:: text_iarchive,GenericMessage&LT;标准::字符串&GT; &GT; :: load_object_ptr(此= 0x8054444,AR = ...,
 X = @ 0x805cb40:0x805cb50,在/usr/include/boost/archive/detail/iserializer.hpp:327 FILE_VERSION = 0)
 #8 0xb7f3839d中的boost ::存档::详细:: basic_iarchive :: load_pointer(无效*放大器;,提振::档案::详细:: basic_pointer_iserializer常量*,提振::档案::详细:: basic_pointer_iserializer常量*(*从/usr/lib/libboost_serialization.so.1.49.0))();)(升压::系列化::常量的extended_type_info&放
 #9 0x0804bea9在boost ::档案::详细:: load_pointer_type&LT;提高::档案:: text_iarchive&GT; ::调用&LT; GenericMes圣人&LT;标准::字符串&GT; * GT; (AR = ...,T = @ 0xbfffef70:0xbfffeff8)
 在/usr/include/boost/archive/detail/iserializer.hpp:524
 #10 0x0804be55在boost ::档案::负荷&LT;提高::档案:: text_iarchive,GenericMessage&LT;标准::字符串&GT; * GT; (AR = ...,T = @ 0xbfffef70:0xbfffeff8)
 在/usr/include/boost/archive/detail/iserializer.hpp:592
 #11 0x0804be36在boost ::档案::详细:: common_iarchive&LT;提高::档案:: text_iarchive&GT; :: load_override&LT;根儿icMessage&LT;标准::字符串&GT; * GT; (此= 0xbfffef84,T = @ 0xbfffef70:0xbfffeff8)
  在/usr/include/boost/archive/detail/common_iarchive.hpp:66
 #12 0x0804be14在boost ::档案:: basic_text_iarchive&LT;提高::档案:: text_iarchive&GT; :: load_override&LT; GenericMe ssage&LT;标准::字符串&GT; * GT; (此= 0xbfffef84,T = @ 0xbfffef70:0xbfffeff8)
  在/usr/include/boost/archive/basic_text_iarchive.hpp:65
 #13 0x0804bdf2在boost ::档案:: text_iarchive_impl&LT;提高::档案:: text_iarchive&GT; :: load_override&LT; GenericMes圣人&LT;标准::字符串&GT; * GT; (此= 0xbfffef84,T = @ 0xbfffef70:0xbfffeff8)
  在/usr/include/boost/archive/text_iarchive.hpp:82
 #14 0x0804bcec在boost ::档案::详细:: interface_iarchive&LT;提高::档案:: text_iarchive&GT; ::运算&GT;&GT; &LT; GenericMessage&LT;标准::字符串&GT; * GT; (此= 0xbfffef84,T = @ 0xbfffef70:0xbfffeff8)
 在/usr/include/boost/archive/detail/interface_iarchive.hpp:60
 #15 0x0804b2a1在main()在TestBE.cxx:28

code SNIPPET 2(GenericMessage.hxx)

 的#include&LT;&iostream的GT;
#包括LT&;串GT;
#包括LT&;&sstream GT;
#包括LT&;升压/系列化/ serialization.hpp&GT;
#包括LT&;升压/存档/ text_oarchive.hpp&GT;
#包括LT&;升压/存档/ text_iarchive.hpp&GT;模板&LT;类T&GT;
类GenericMessage {
上市:
  GenericMessage():
    beId(-1),
    数据(NULL)
  {}  GenericMessage(INT ID,T MSG):
    beId(ID),
    数据(MSG)
  {}  〜GenericMessage(){}  ŧ的getData()
  {
    返回的数据;
  }
  标准::字符串的toString()
  {
     的std :: ostringstream SS;
     SS&LT;&LT; getBeId();
     标准::字符串RET = ss.str();    返回RET;
  }  无效setBeId(INT ID)
  {
    beId = ID;
  }  INT getBeId()
  {
    返回beId;
  }
  私人的:
      友元类的boost ::系列化::访问;  INT beId;
  数据T;
  模板&LT;类归档和GT;
  无效连载(归档和放大器; AR,const的无符号整型版)
  {
      AR&安培; beId;
      AR&安培;数据;
  } };

code SNIPPET 3(ZmqHandler.hxx)

 的#includezmq.hpp
#包括GenericMessage.hxx
#包括LT&;&unistd.h中GT;
#包括LT&;&了cassert GT;模板&LT;类A&GT;
类ZmqHandler {
上市:ZmqHandler():
mContext(1),
mOutbHandlerSocket(mContext,ZMQ_PUSH)
{
    mOutbHandlerSocket.bind(TCP:// *:5555);
}
〜ZmqHandler(){}无效sendToBE(GenericMessage&LT; A&GT; * theMsg)
{
   的std :: ostringstream archive_stream;
   提高::档案:: text_oarchive的存档(archive_stream);   尝试
   {
     归档&LT;&LT; theMsg;
   }赶上(升压::档案:: archive_exception&安培;除息){
      性病::法院LT&;&LT; 反序列化过程中存档例外:&LT;&LT;的std :: ENDL;
      性病::法院LT&;&LT; ex.what()&所述;&下;的std :: ENDL;
   }赶上(INT E){
       性病::法院LT&;&LT; EXCEPTION&LT;&LT; E&LT;&LT;的std :: ENDL;
   }   标准::字符串outbound_data_ = archive_stream.str();
   为const char * BUF = outbound_data_.c_str();
   INT LEN = strlen的((为const char *)BUF);
   性病::法院LT&;&LT; 长度[&LT;&LT; LEN&LT;&LT; ]&LT;&LT;的std :: ENDL;   ZMQ :: message_t msgToSend(LEN);   的memcpy((字符*)msgToSend.data(),BUF,LEN);   如果(memcmp((字符*)msgToSend.data(),BUF,LEN)!= 0)
   {
     性病::法院LT&;&LT; 的memcpy错误! &LT;&LT;的std :: ENDL;
   }   mOutbHandlerSocket.send(msgToSend);
   性病::法院LT&;&LT; 发送的请求:&LT;&LT; theMsg-&GT;的toString()&LT;&LT; ]&LT;&LT;的std :: ENDL;
 }  私人的:
     ZMQ :: context_t mContext;
     ZMQ :: socket_t mOutbHandlerSocket;
 };

code SNIPPET 4(TestFE.cxx)

 的#includeZmqHandler.hxx  诠释的main()
  {
     ZmqHandler&LT;标准::字符串&GT; zmqHandler;
     INT计数器= 1;     而(1)
     {
        性病::字符串数据=你好\\ 0!;
        GenericMessage&LT;标准::字符串&GT;味精(计数器,数据);
        zmqHandler.sendToBE(安培;味精);
        反++;
       睡眠(1);
      }    返回0;
 }

code SNIPPET 5(TestBE.cxx)

 的#includezmq.hpp
 #包括GenericMessage.hxx
 #包括LT&;&的fstream GT; 诠释的main()
 {
    // prepare我们的背景和插座
    ZMQ :: context_t上下文(1);
    ZMQ :: socket_t插座(背景下,ZMQ_PULL);    性病::法院LT&;&LT; 连接到FE ......&LT;&LT;的std :: ENDL;
    socket.connect(TCP://本地主机:5555);    而(1){
       ZMQ :: message_t回复;
       socket.recv(安培;回复);       为const char * BUF =的static_cast&LT;为const char *&GT;(reply.data());
       性病::法院LT&;&LT; CHAR [&LT;&LT; BUF&LT;&LT; ]&LT;&LT;的std :: ENDL;       标准::字符串input_data_(BUF);
       的std :: istringstream archive_stream(input_data_);
       提高::档案:: text_iarchive存档(archive_stream);
       GenericMessage&LT;标准::字符串&GT; * theMsg;       尝试
       {
       / * !!!!!!!!!!管线28是以下!!!!!!!!!! * /
         归档&GT;&GT; theMsg;
       }赶上(升压::档案:: archive_exception&安培;除息){
          性病::法院LT&;&LT; 反序列化过程中存档例外:&LT;&LT;的std :: ENDL;
          性病::法院LT&;&LT; ex.what()&所述;&下;的std :: ENDL;
       }赶上(INT E){
          性病::法院LT&;&LT; EXCEPTION&LT;&LT; E&LT;&LT;的std :: ENDL;
       }       性病::法院LT&;&LT; ID&LT;&LT; theMsg-&GT; getBeId()&所述;&下;的std :: ENDL;
       性病::法院LT&;&LT; 数据&LT;&LT; theMsg-&GT;的getData()&LT;&LT;的std :: ENDL;     }    返回0;
   }


解决方案

您声明 theMsg 作为指针( GenericMessage&LT;标准::字符串&GT; * theMsg;

试着改变该行 GenericMessage&LT;标准::字符串&GT; theMsg; .`

你的异常的真正根源

GenericMessage 默认的构造函数,初始化数据 NULL 。但是,你不能初始化的std ::字符串 NULL 指针。不要在默认的构造函数初始化数据成员。

  GenericMessage()
:beId(-1)
{}

只要你键入 T 有一个默认的构造函数,当产生编译器将处理它的初始化的模板。

(希望)有用的提示#1

在数据缓冲区中的 ZMQ :: message_t (通常)不是空终止。收到消息后,要小心你如何转换缓冲区的字符串。

  // SNIP
ZMQ :: message_t回复;
socket.recv(安培;回复);为const char * BUF =的static_cast&LT;为const char *&GT;(reply.data());
性病::法院LT&;&LT; CHAR [&LT;&LT; BUF&LT;&LT; ]&LT;&LT;的std :: ENDL;//标准::字符串input_data_(BUF); //假定一个空字符串项
标准::字符串input_data_(BUF,reply.size());
// SNIP

(希望)有用的提示#2

另外,我注意到,在一些 ZmqHandler.hxx

  // SNIP
标准::字符串outbound_data_ = archive_stream.str();
为const char * BUF = outbound_data_.c_str();
INT LEN = strlen的((为const char *)BUF);
性病::法院LT&;&LT; 长度[&LT;&LT; LEN&LT;&LT; ]&LT;&LT;的std :: ENDL;ZMQ :: message_t msgToSend(LEN);的memcpy((字符*)msgToSend.data(),BUF,LEN);如果(memcmp((字符*)msgToSend.data(),BUF,LEN)!= 0)
{
  性病::法院LT&;&LT; 的memcpy错误! &LT;&LT;的std :: ENDL;
}
// SNIP

您不需要检查的memcpy的结果(除非您要检查它的返回值)。整个模块都可以改变这样的:

 的std ::字符串outbound_data_ = archive_stream.str();
//没有必要使用C风格的字符串函数'strlen的
INT LEN = outbound_data_.length();
性病::法院LT&;&LT; 长度[&LT;&LT; LEN&LT;&LT; ]&LT;&LT;的std :: ENDL;ZMQ :: message_t msgToSend(LEN);
的memcpy(msgToSend.data(),outbound_data_.data(),LEN);

The text I am writing here is a follow up problem that I opened up earlier in another thread at Boost: Serializing/De-serializing a custom C++ object passed over ZeroMQ pull socket. The compilation problems in the earlier thread have been resolved by using a textarchive type rather than binaryarchive but now I experience a runtime problem when de-serializing. I repeat the earlier text here with a new problem statement for your convenience. I am relatively new to C++ realm and appreciate any further help.

Description:

I have a C++ class named GenericMessage which simply holds an id and data as its members (See code snippet 2 below - GenericMessage.hxx). My intention is to serialize an instance of this class and send it via a ZeroMQ socket which implements the push pattern.

The serialization and sending task has been implemented in class ZMQHandler (see sendToBE function) which is placed in a header file name ZMQHandler.hxx shown in the code snippet 3 below. This class is instantiated by TestFE.cxx shown in the 4rd code snippet below.

The receiving and de-serialization of the GenericMessage instance is implemented in TestBE.cxx available in the 5th code snippet below. My intention is to receive the GenericMessage instance over the ZMQ socket (i.e. pull socket), de-serialize it and then print its members to standard output.

Problem Statement:

When I run the receiver (i.e. TestBE.cxx) I verified here that I can transfer data from TestFE.cxx to TEstBE.cxx over the ZMQ socket. However, I got an exception shown in the 1st code snippet below exactly when I attempt to de-serialize the input archive at line 28 in TestBE.cxx (see the 5th code snippet very below, line 28 has been marked).

Is there something I am missing in this de-serialization procedure implemented in TestBE.cxx in code snippet 5? Why do you think I am getting this exception? Could it be that I am missing st in the serialization procedure implemented in ZMQHandler.cxx (code snippet 3 - function sendToBE). Thanks in advance.

CODE SNIPPET 1 GDB OUTPUT & backtrace

$ gdb TestBE 
GNU gdb (GDB) 7.5-ubuntu
.....
(gdb) r
 Starting program: /TestBE 
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
 [New Thread 0xb7c12b40 (LWP 16644)]
 [New Thread 0xb7411b40 (LWP 16645)]
 Connecting to FE...

!!!!!!!!!!!!!!!!!!!!HERE BEGINS!!!!!!!!!!!!!!!!!!!!!!!!!!!

 **CHAR [22 serialization::archive 9 0 1 0
 0 1 12 Hello there!]
 terminate called after throwing an instance of 'std::logic_error'
 what():  basic_string::_S_construct null not valid**

!!!!!!!!!!!!!!!!!!!!HERE END !!!!!!!!!!!!!!!!!!!!!!!!!!!

 Program received signal SIGABRT, Aborted.
 0xb7fdd424 in __kernel_vsyscall ()
 (gdb) bt
 #0  0xb7fdd424 in __kernel_vsyscall ()
 #1  0xb7c7a1df in raise () from /lib/i386-linux-gnu/libc.so.6
 #2  0xb7c7d825 in abort () from /lib/i386-linux-gnu/libc.so.6
 #3  0xb7e608ad in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/i386-  linux-gnu/libstdc++.so.6
 #4  0xb7e5e4f3 in ?? () from /usr/lib/i386-linux-gnu/libstdc++.so.6
 #5  0xb7e5e52f in std::terminate() () from /usr/lib/i386-linux-gnu/libstdc++.so.6
 #6  0xb7e5e825 in __cxa_rethrow () from /usr/lib/i386-linux-gnu/libstdc++.so.6
 #7  0x0804c1d4 in    boost::archive::detail::pointer_iserializer<boost::archive::text_iarchive,    GenericMessage<std::string> >::load_object_ptr (this=0x8054444, ar=..., 
 x=@0x805cb40: 0x805cb50, file_version=0) at    /usr/include/boost/archive/detail/iserializer.hpp:327
 #8  0xb7f3839d in boost::archive::detail::basic_iarchive::load_pointer(void*&,  boost::archive::detail::basic_pointer_iserializer const*,  boost::archive::detail::basic_pointer_iserializer const* (*) (boost::serialization::extended_type_info const&)) () from  /usr/lib/libboost_serialization.so.1.49.0
 #9  0x0804bea9 in    boost::archive::detail::load_pointer_type<boost::archive::text_iarchive>::invoke<GenericMes     sage<std::string>*> (ar=..., t=@0xbfffef70: 0xbfffeff8)
 at /usr/include/boost/archive/detail/iserializer.hpp:524
 #10 0x0804be55 in boost::archive::load<boost::archive::text_iarchive,                                  GenericMessage<std::string>*> (ar=..., t=@0xbfffef70: 0xbfffeff8)
 at /usr/include/boost/archive/detail/iserializer.hpp:592
 #11 0x0804be36 in   boost::archive::detail::common_iarchive<boost::archive::text_iarchive>::load_override<Gener icMessage<std::string>*> (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
  at /usr/include/boost/archive/detail/common_iarchive.hpp:66
 #12 0x0804be14 in  boost::archive::basic_text_iarchive<boost::archive::text_iarchive>::load_override<GenericMe ssage<std::string>*> (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
  at /usr/include/boost/archive/basic_text_iarchive.hpp:65
 #13 0x0804bdf2 in boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load_override<GenericMes sage<std::string>*> (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
  at /usr/include/boost/archive/text_iarchive.hpp:82
 #14 0x0804bcec in      boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator>> <GenericMessage<std::string>*> (this=0xbfffef84, t=@0xbfffef70: 0xbfffeff8)
 at /usr/include/boost/archive/detail/interface_iarchive.hpp:60
 #15 0x0804b2a1 in main () at TestBE.cxx:28

CODE SNIPPET 2 (GenericMessage.hxx)

#include <iostream>
#include <string>
#include <sstream>
#include <boost/serialization/serialization.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 Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
      ar & beId;
      ar & data;
  }

 };

CODE SNIPPET 3 (ZmqHandler.hxx)

#include "zmq.hpp"
#include "GenericMessage.hxx"
#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::ostringstream archive_stream;
   boost::archive::text_oarchive archive(archive_stream);

   try
   {
     archive << theMsg;
   } catch (boost::archive::archive_exception& ex) {
      std::cout << "Archive Exception during deserializing:" << std::endl;
      std::cout << ex.what() << std::endl;           
   } catch (int e) {
       std::cout << "EXCEPTION " << e << std::endl; 
   }

   std::string outbound_data_ = archive_stream.str();
   const char * buf = outbound_data_.c_str();    
   int len = strlen((const char*)buf);
   std::cout << "LENGTH [" << len << "]" << std::endl;

   zmq::message_t msgToSend(len);

   memcpy ((char *) msgToSend.data(), buf, len);

   if(memcmp((char *) msgToSend.data(), buf, len) != 0)
   {
     std::cout << "memcpy error!" << std::endl;
   }

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

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

CODE SNIPPET 4 (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 5 (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);

       const char *buf = static_cast<const char*>(reply.data());
       std::cout << "CHAR [" << buf << "]" << std::endl;

       std::string input_data_(buf); 
       std::istringstream archive_stream(input_data_);
       boost::archive::text_iarchive archive(archive_stream);
       GenericMessage<std::string> *theMsg;

       try
       {
       /* !!!!!!!!!! LINE 28 is the following !!!!!!!!!!*/
         archive >> theMsg;
       } catch (boost::archive::archive_exception& ex) {
          std::cout << "Archive Exception during deserializing:" << std::endl;
          std::cout << ex.what() << std::endl;           
       } catch (int e) {
          std::cout << "EXCEPTION " << e << std::endl; 
       }

       std::cout << "ID" << theMsg->getBeId() << std::endl; 
       std::cout << "Data" << theMsg->getData() << std::endl; 

     }

    return 0;
   }

解决方案

You declared theMsg as a pointer (GenericMessage<std::string> *theMsg;).

Try changing that line to GenericMessage<std::string> theMsg;.`

The real source of your exception

In the GenericMessage default constructor, you initialize data with NULL. However, you aren't allowed to initialize a std::string with a NULL pointer. Don't initialize your data member in the default constructor.

GenericMessage()
: beId(-1) 
{}

As long as your type T has a default constructor, the compiler will handle its initialization when the template is generated.

(hopefully) helpful hint #1

The data buffer in a zmq::message_t is (generally) not NULL-terminated. After you receive the message, be careful about how you convert the buffer to a string.

// snip
zmq::message_t reply;
socket.recv (&reply);

const char *buf = static_cast<const char*>(reply.data());
std::cout << "CHAR [" << buf << "]" << std::endl;

//std::string input_data_(buf);  // assumes a null-term string
std::string input_data_( buf, reply.size() ); 
// snip

(hopefully) helpful hint #2

Also, I noticed something in ZmqHandler.hxx.

// snip
std::string outbound_data_ = archive_stream.str();
const char * buf = outbound_data_.c_str();    
int len = strlen((const char*)buf);
std::cout << "LENGTH [" << len << "]" << std::endl;

zmq::message_t msgToSend(len);

memcpy ((char *) msgToSend.data(), buf, len);

if(memcmp((char *) msgToSend.data(), buf, len) != 0)
{
  std::cout << "memcpy error!" << std::endl;
}
// snip

You don't need to check the results of the memcpy (unless you want to check its return value). The whole block could be changed to something like this:

std::string outbound_data_ = archive_stream.str();
// no need to use the c-style string function 'strlen'
int len = outbound_data_.length();
std::cout << "LENGTH [" << len << "]" << std::endl;

zmq::message_t msgToSend(len);
memcpy( msgToSend.data(), outbound_data_.data(), len );

这篇关于升压:反序列化的自定义C ++对象越过ZeroMQ拉插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆