2

I´m reading a message queue, using Boost.Serialization (v1.46). Everything works fine as long as the queue contains only one element. But when I read a queue which contains more than one element the, following exception is thrown:

terminate called after throwing an instance of 'boost::archive::archive_exception'
what():  invalid signature

The archive_exception.hpp says invalid signature // first line of archive does not contain expected string"

The class I´m serializing and deserializing looks as followed:

#define MAX_SIZE 1000

class IpcMsg {

public:
    IpcMsg(int logLevel = 0, std::string logMsg = "") :
            logLevel(logLevel), logMsg(logMsg) {
    }
    ;

    int logLevel;
    std::string logMsg;

private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version) {
        ar & logLevel;
        ar & logMsg;
    }
};

serializing :

try
    {
        message_queue mq
            (
             open_or_create,
             "mq",
             100,
             MAX_SIZE
            );

        IpcMsg logMsg(1, "Test");

        std::stringstream oss;

        boost::archive::text_oarchive oa(oss);
        oa << logMsg;

        std::string serialized_string(oss.str());
        mq.send(serialized_string.data(), serialized_string.size(), 0);
    }
    catch(interprocess_exception &ex)
    {
        std::cerr << ex.what() << std::endl;
    }

deserializing:

...
IpcMsg logEntry;

std::stringstream iss;
std::string serialized_string;
serialized_string.resize(MAX_SIZE);

while(mq.try_receive(&serialized_string[0], MAX_SIZE, recvd_size, priority)){

    iss << serialized_string;

    boost::archive::text_iarchive ia(iss);
    ia >> logEntry;

     msgs.push_back(logEntry);

     std::cout << logEntry.logLevel << std::endl;
     std::cout << logEntry.logMsg << std::endl;
}

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246

1 Answers1

1

This code creates a std::stringstream consisting of the message followed by up to MAX_SIZE null characters.

serialized_string.resize(MAX_SIZE);
mq.try_receive(&serialized_string[0], MAX_SIZE, recvd_size, priority);
iss << serialized_string;

I'm guessing Boost.Serialization is hitting the NULL characters that are after the first message and erroring out.

Maybe you could try something like this instead?

serialized_string.resize(MAX_SIZE);
mq.try_receive(&serialized_string[0], MAX_SIZE, recvd_size, priority);
serialized_string.resize(recvd_size);
iss << serialized_string;

(Also, I'm not personally a fan of code like &serialized_string[0]. See here, here. A vector<char> or smart pointer to a plain old char[] might be better.)

Community
  • 1
  • 1
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246