title: Boost: Serializing/De-serializing a custom C++ object passed over ZeroMQ pull socket
body: <p><strong>Description:</strong></p>
  
  <p>I have a C++ class named <strong>GenericMessage</strong> which simply holds an id and data as its members (See code snippet 1 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. </p>
  
  <p>The serialization and sending task has been implemented in <strong>class ZMQHandler</strong> (see sendToBE function) which is placed in a header file name ZMQHandler.hxx shown in the <strong>code snippet 2</strong> below. This class is instantiated by <strong>TestFE.cxx</strong> shown in <strong>the 3rd code snippet</strong> below.</p>
  
  <p>The receiving and de-serialization of the GenericMessage instance is implemented in <strong>TestBE.cxx</strong>  available in the <strong>4th code snippet</strong> below. My intentiton is to receive the GenericMessage instance over the ZMQ socket (i.e. pull socket), de-serialize it and then print its members. </p>
  
  <p><strong>Problem:</strong></p>
  
  <p>The problem is that when I compile TestBE.cxx, I am having a number of compilation errors involving template functions. Considering the code in TestBE.cxx, can anyone tell me what I am missing in de-serialization part that is marked with comments in the 4th code snippets? I am relatively a new C++ programmer and wonder how I should interpret these template functions related compilation errors which have been listed at the bottom of this text (i.e. the final snippet). Line 18 where the compilation error originates is marked in the 4th code snippet. Thanks.</p>
  
  <p><strong>CODE SNIPPET 1 (GenericMessage.hxx)</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;sstream&gt;
  #include &lt;boost/serialization/serialization.hpp&gt;
  #include &lt;boost/archive/binary_oarchive.hpp&gt;
  #include &lt;boost/archive/binary_iarchive.hpp&gt;
  #include &lt;boost/archive/text_oarchive.hpp&gt;
  #include &lt;boost/archive/text_iarchive.hpp&gt;
  
  template &lt;class T&gt;
  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 &lt;&lt; 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 &lt;class Archieve&gt;
              void serialize(Archieve &amp; ar, const unsigned int version)
              {
                 ar &amp; beId;
                 ar &amp; data;
              }
  
   };
  </code></pre>
  
  <p><strong>CODE SNIPPET 2 (ZMQHandler.hxx)</strong></p>
  
  <pre><code> #include "zmq.hpp"
   #include "GenericMessage.hxx"
   #include &lt;pthread.h&gt;
   #include &lt;unistd.h&gt;
   #include &lt;cassert&gt;
  
  template &lt;class A&gt;
  class ZmqHandler {
  public:
  
         ZmqHandler():
     mContext(1),
     mOutbHandlerSocket(mContext, ZMQ_PUSH)
         {    
              mOutbHandlerSocket.bind ("tcp://*:5555");       
         }
  
         ~ZmqHandler() {}
  
          void sendToBE(GenericMessage&lt;A&gt; &amp;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 &lt;&lt; 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 &lt;&lt; "SENT request: [" &lt;&lt; theMsg.toString() &lt;&lt; "]" &lt;&lt; std::endl;
  }   
  
      private:  
            zmq::context_t mContext;
            zmq::socket_t mOutbHandlerSocket;         
  };
  </code></pre>
  
  <p><strong>CODE SNIPPET 3 (TestFE.cxx)</strong></p>
  
  <pre><code> #include "ZmqHandler.hxx"
  
   int main ()
   {
     ZmqHandler&lt;std::string&gt; zmqHandler;
     int counter = 1;
  
     while(1)
     {  
       std::string data = "Hello there!\0";
       GenericMessage&lt;std::string&gt; msg(counter, data);
       zmqHandler.sendToBE(msg);
       counter++;
       sleep(1);
      }
  
      return 0;
   }     
  </code></pre>
  
  <p><strong>CODE SNIPPET 4 (TestBE.cxx)</strong></p>
  
  <pre><code> #include "zmq.hpp"
   #include "GenericMessage.hxx"
   #include &lt;fstream&gt;
  
   int main ()
   {
      //  Prepare our context and socket
      zmq::context_t context (1);
      zmq::socket_t socket (context, ZMQ_PULL);
  
     std::cout &lt;&lt; "Connecting to FE..." &lt;&lt; std::endl;
     socket.connect ("tcp://localhost:5555");
  
     while(1){
         zmq::message_t reply;
         socket.recv (&amp;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&lt;std::string&gt; msg;
         ia &gt;&gt; msg;
  
         std::cout &lt;&lt; "RECEIVED: " &lt;&lt; msg.toString() &lt;&lt; std::endl;
         std::cout &lt;&lt; "DATA: " &lt;&lt; ((std::string)msg.getData())  &lt;&lt; std::endl;
      }
  
       return 0;
   }
  </code></pre>
  
  <p><strong>Compilation OUTPUT of TestBE.cxx</strong></p>
  
  <pre><code> 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&amp; {aka const std::basic_string&lt;char&gt;&amp;}’ [-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&lt;_CharT, _Traits, _Alloc&gt;::basic_string(const _CharT*, const _Alloc&amp;)  [with _CharT = char; _Traits = std::char_traits&lt;char&gt;; _Alloc = std::allocator&lt;char&gt;] &lt;near  match&gt;
    /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&lt;_CharT, _Traits, _Alloc&gt;::basic_string(const _CharT*, const _Alloc&amp;) [with _CharT = char; _Traits = std::char_traits&lt;char&gt;; _Alloc = std::allocator&lt;char&gt;]’ [-fpermissive]
         make: *** [TestBE.o] Error 1
  </code></pre>