3

説明:

GenericMessageという名前のC++クラスがあり、そのメンバーとしてIDとデータを保持しているだけです(以下のコードスニペット1-GenericMessage.hxxを参照)。私の意図は、このクラスのインスタンスをシリアル化し、プッシュパターンを実装するZeroMQソケットを介して送信することです。

シリアル化と送信のタスクは、以下のコードスニペット2に示されているヘッダーファイル名ZMQHandler.hxxに配置されているクラスZMQHandler (sendToBE関数を参照)に実装されています。このクラスは、以下の3番目のコードスニペットに示されているTestFE.cxxによってインスタンス化されます。

GenericMessageインスタンスの受信と逆シリアル化は、以下の4番目のコードスニペット で利用可能なTestBE.cxxに実装されています。私の意図は、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のコンストラクターにはタイプopenmodeまたはstd::stringのいずれかが必要であり、タイプのパラメーターを渡しましたvoid*(の戻り値reply.data())。

代わりに、受信したメッセージをバイナリ ファイルにダンプすることもできますが、それでもキャストを行う必要があります。

于 2013-01-23T13:09:26.777 に答える