Description:
I have a C ++ class called GenericMessage that simply contains an identifier 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 through the ZeroMQ socket, which implements the push pattern.
The serialization and sending task was implemented in the ZMQHandler class (see the sendToBE function), which is placed in the name of the ZMQHandler.hxx header file, shown in code fragment 2 below. This class is created by TestFE.cxx , shown below in the code snippet .
Getting and deserializing an instance of GenericMessage is done in TestBE.cxx , available in the fourth code snippet below. My intention is to get an instance of GenericMessage through a ZMQ socket (i.e. a Pull socket), de-serialize it, and then print its elements.
Problem:
The problem is that when I compile TestBE.cxx, I get a number of compilation errors related to the template functions. Given the code in TestBE.cxx, can someone tell me what I am missing in terms of de-serialization, which is marked by comments in the fourth code snippets? I am a relatively new C ++ programmer and am wondering how I should interpret these errors in the templates related to compilation errors that are listed at the bottom of this text (i.e. the Final fragment). Line 18, in which a compilation error occurs, is marked in the fourth code fragment. Thank.
CODE SNIPPET 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;
}
};
CODE SNIPPET 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;
};
CODE SNIPPET 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;
}
CODE SNIPPET 4 (TestBE.cxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <fstream>
int main ()
{
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);
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;
}
Compiling OUTPUT of 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