2

我知道如何通过以下方式序列化对象:

void encodeMsg(char **msg, const ConnectionParams& params)
{
    std::ostringstream oss;
    if (!(oss << params))
    {
        //failure
    }
    msg = oss.str();
}

如何将消息反序列化回对象?

意思是我想要这个方法:

ConnectionParams encodeMsg(char *msg)
    { ... }

所以我没有 instringstream 对象......我该怎么做?

4

1 回答 1

1

就像是:

ConnectionParams decodeMsg(char *msg)
{
  ConnectionParams ret;
  std::istringstream iss(msg);
  iss >> ret;
  return ret;
}

这是假设这个类是可序列化的operator<<,并提供对称相反的操作operator>>。在不知道其内部结构的情况下,无法序列化任意 C++ 对象,在此答案中,我假设这些操作已由类提供程序实现。

另外,请注意,您可能应该将 ConnectionParams 作为参考传递,例如:

void encodeMsg(char *msg, ConnectionParams& ret);

此外,您的 encodeMsg 是错误的,有更好的机会作为:

void encodeMsg(char **msg, const ConnectionParams& params)
{
    ....
    *msg = oss.str();
}

甚至这是错误的,因为 oss.str() 从 oss 返回一个内部指针,并且不能将其返回给调用者,因为函数返回时 oss 将被销毁,并且该指针将无效。你最好返回一个 std::string 或类似的东西。

编辑:如果该类不提供序列化和反序列化自身的方法怎么办?在足够简单的类上,不保存在堆上分配的指针,也不保存文件描述符,也不对构造函数和析构函数有奇特的行为,你可以用旧的 C 结构做同样的事情:解释它的所有字节作为缓冲区。请注意,这是危险的,类型不安全,并且缓冲区可能无法在不同的编译器/架构之间互操作。

// DISCLAIMER: Untested code!

class A {
  int plain_variable;
  char palin_array[50];
};
// Class A is ok to serialize this way

class B {
  A plain_object_array[10];
  double another_plain_variable;
};
// Class B is ok to serialize this way

class C {
  float plain_object;
  std::string fancy_string;
};
// Class C is *NOT* ok to serialize this way, because it contains an string,
// which, in turn, contains a heap allocated pointer

template<class T>
void serialize(const T& obj, std::string& buff)
{
  const char *accessor = (const char *)&obj;
  std::string tmp(accessor, sizeof(obj));
  std::swap(buff, tmp);
}

template<class T>
void deserialize(const std::string& buff, T& obj)
{
  char *accessor = (char *)&obj;
  std::copy(buff.begin(), buff.end(), accessor);
}

看,这个方案的工作条件是,你不太可能将它与第三方提供的类一起使用。最后,您可能需要自己存储重建对象所需的所有数据,并处理这些数据。

于 2012-06-17T17:15:50.073 回答