2013-01-23 30 views
3

描述:升壓:串行化/解串行化的自定義C++對象越過ZeroMQ拉插座

我有一個名爲GenericMessage C++類簡單地持有的ID和數據作爲其成員(見代碼段1下面 - GenericMessage.hxx)。我的意圖是序列化這個類的一個實例,並通過ZeroMQ套接字發送它,該套接字實現了push模式。

序列化和發送任務已經類ZMQHandler得到實施(參見sendToBE函數),其被放置在低於2的代碼段中所示的頭文件名ZMQHandler.hxx。該類由TestFE.cxx實例化,如所示,下面的第三個代碼段

的GenericMessage實例的接收和反序列化在TestBE.cxx可用來實現在下面的第四代碼段。我的意圖是通過ZMQ套接字(即拉套接字)接收GenericMessage實例,對其進行反序列化,然後打印其成員。

問題:

的問題是,當我編譯TestBE.cxx,我有一些涉及模板函數編譯錯誤。考慮到TestBE.cxx中的代碼,任何人都可以告訴我我在第四代碼片段中的註釋標記的反序列化部分中缺少什麼?我相對來說是一個新的C++程序員,不知道我應該如何解釋這些模板函數相關的編譯錯誤,這些錯誤已經列在本文的底部(即最終片段)。第四行代碼片段中標記了編譯錯誤發生的第18行。謝謝。

代碼段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)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; 
} 

編譯輸出

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 

回答

1

我認爲該錯誤消息是相當清楚的:constructor of stringstream需要任一類型openmodestd::string,並且您傳遞了void*(返回reply.data())類型的參數。

您可以將收到的消息轉儲到二進制文件中,但您仍需要進行一些轉換。

+0

編譯問題通過使用textarchieve而不是二進制存檔來解決。 –

+0

我在這裏發佈了後續問題:http://stackoverflow.com/questions/14565538/boost-de-serializing-a-custom-c-object-passed-over-zeromq-pull-socket –