在我必须维护的代码中,一些数组序列化(例如std::vector<T>
)大致按以下方式发生:有一个array_t
没有填充的结构:
#pragma pack(push, 1)
template <typename T, uint32_t N>
struct array_t
{
typedef T value_type;
static uint32_t const max_length = N;
uint32_t length;
value_type data[max_length];
value_type const & operator[](uint32_t k) { return data[k]; }
value_type & operator[](uint32_t k) { return data[k]; }
template <typename Container>
void from_container(Container const & c)
{
std::copy(c.begin(), c.end(), &(*this)[0]);
length = c.size();
}
template <typename Container>
Container to_container() const
{
return Container(&(*this)[0], &(*this)[length]);
}
};
#pragma pack(pop)
当需要通过网络发送此类数据类型时,会发生什么(非常简化):
template <typename T>
char * serialize(T const & data)
{
void * buf = std::malloc(sizeof(T));
std::memcpy(buf, &data, sizeof(T));
return reinterpret_cast<char *>(buf);
}
std::string const s("This is some string");
typedef array_t<char, 64> arr_str;
arr_str serial;
serial.from_container(s);
char * buf = serialize(serial);
network.send(buf); // frees the memory as well
而在另一端,这个方法被称为:
template <typename T>
T deserialize(char * ptr)
{
T data;
std::memcpy(&data, ptr, sizeof(T));
std::free(ptr);
return data;
}
arr_str deserial = deserialize<arr_str>(buf);
我们不需要争辩说这不是序列化对象的最佳方式。我现在关心的是:它的便携性如何?这些方法的评论说这可以保证在每个 x86/x64 系统上都有效——这是真的吗?