3

描述:

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

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

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

问题:

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

代码片段 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;
            }

 };

代码片段 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;         
};

代码片段 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;
 }     

代码片段 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
4

1 回答 1

1

我想说错误信息很清楚:stringstream 的构造函数需要 typeopenmodestd::string,并且您传递了一个类型的参数void*(返回reply.data())。

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

于 2013-01-23T13:09:26.777 回答