boost ::序列化文本存档的不同行为

时间:2013-07-03 09:18:26

标签: boost g++ stdstring boost-serialization

我在std::string上使用boost::serialization序列化text_oarchive时出现问题。 AFAICT,我有两个相同的代码片段,在两个不同的程序中表现不同。

这是我认为行为正确的程序:

#include <iostream>
#include <string>
#include <sstream>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

template <typename T>
void serialize_deserialize(const T & src, T & dst)
{
    std::string serialized_data_str;

    std::cout << "original data: " << src << std::endl;

    std::ostringstream archive_ostream;
    boost::archive::text_oarchive oarchive(archive_ostream);
    oarchive << src;
    serialized_data_str = archive_ostream.str();
    std::cout << "serialized data: " << serialized_data_str << std::endl;

    std::istringstream archive_istream(serialized_data_str);
    boost::archive::text_iarchive iarchive(archive_istream);
    iarchive >> dst;
}


int main() 
{
    std::string archived_data_str = "abcd";
    std::string restored_data_str;

    serialize_deserialize<std::string>(archived_data_str, restored_data_str);

    std::cout << "restored data: " << restored_data_str << std::endl;

    return 0;
}

这是它的输出:

original data: abcd
serialized data: 22 serialization::archive 10 4 abcd
restored data: abcd

(您可以使用以下代码进行编译:{{1​​}})

另一方面,这个是我正在编写的程序的摘录(源自boost_asio/example/serialization/connection.hpp),它序列化g++ boost-serialization-string.cpp -o boost-serialization-string -lboost_serialization数据,以十六进制表示形式转换每个字符:

std::string

这是其输出的摘录:

/// Asynchronously write a data structure to the socket.
template <typename T, typename Handler>
void async_write(const T& t, Handler handler)
{
  // Serialize the data first so we know how large it is.
  std::cout << "original data: " << t << std::endl;
  std::ostringstream archive_stream;
  boost::archive::text_oarchive archive(archive_stream);
  archive << t;
  outbound_data_ = archive_stream.str();
  std::cout << "serialized data: " << outbound_data_ << std::endl;
  [...]

版本(original data: abcd serialized data: 22 serialization::archive 10 5 97 98 99 100 0 )是一样的,对吧?所以这应该证明我在两个程序中使用相同的序列化库。

然而,我真的无法弄清楚这里发生了什么。我现在几乎整整一个工作日都试图解决这个难题,而且我没有想法。

对于可能想要重现此结果的任何人,只需下载Boost serialization example即可添加以下内容

10

connection_.async_write("abcd", boost::bind(&client::handle_write, this, boost::asio::placeholders::error)); 的第50行,在client.cpp中添加以下成员函数

client.cpp

添加此/// Handle completion of a write operation. void handle_write(const boost::system::error_code& e) { // Nothing to do. The socket will be closed automatically when the last // reference to the connection object goes away. }

cout

std::cout << "serialized data: " << outbound_data_ << std::endl;

并编译:

connection.hpp:59

我在g++ -O0 -g3 client.cpp -o client -lboost_serialization -lboost_system g++ -O0 -g3 server.cpp -o server -lboost_serialization -lboost_system 下使用g++ 4.8.1 Ubuntu 13.04 64bit

非常感谢任何帮助。

P.S。我发布这个是因为Boost 1.53的反序列化根本不起作用! :)

1 个答案:

答案 0 :(得分:1)

我看到了这种行为的两个原因。

  1. 编译器未将"abcd"const char *显式转换为std::string,并且序列化将其作为“字节”的向量处理,而不是作为ASCII字符串处理。将代码更改为connection_.async_write(std::string("abcd"), boost::bind(&client::handle_write, this, boost::asio::placeholders::error));可以解决问题。
  2. 可能是作为t模板方法的async_write参数传递的字符串类型不是std::string而是std::wstring,并且它不是作为ASCII字符串序列化的(“ abcd“)但作为无符号短向量,97 98 99 100是ASCII字符abcd的十进制表示。