我在Python中使用struct.pack将数据转换为序列化字节流。
>>> import struct
>>> struct.pack('i', 1234)
'\xd2\x04\x00\x00'
C ++中的等价是什么?
答案 0 :(得分:1)
没有。 C ++没有内置的序列化。
您必须将单个对象写入字节数组/向量,并注意endianness(如果您希望代码可移植)。
答案 1 :(得分:1)
从长远来看,使用第三方库(例如Google Protocol Buffers)可能会更好,但如果你坚持自己推出,你的例子的C ++版本可能是这样的:
#include <stdint.h>
#include <string.h>
int32_t myValueToPack = 1234; // or whatever
uint8_t myByteArray[sizeof(myValueToPack)];
int32_t bigEndianValue = htonl(myValueToPack); // convert the value to big-endian for cross-platform compatibility
memcpy(&myByteArray[0], &bigEndianValue, sizeof(bigEndianValue));
// At this point, myByteArray contains the "packed" data in network-endian (aka big-endian) format
相应的“解压缩”代码如下所示:
// Assume at this point we have the packed array myByteArray, from before
int32_t bigEndianValue;
memcpy(&bigEndianValue, &myByteArray[0], sizeof(bigEndianValue));
int32_t theUnpackedValue = ntohl(bigEndianValue);
在现实生活中你可能会打包多个值,这很容易做到(通过使数组大小更大并在循环中调用htonl()和memcpy() - 不要忘记增加memcpy()的第一个参数,所以你的第二个值不会覆盖数组中第一个值的位置,依此类推。)
您也可能想要打包(也就是序列化)不同的数据类型。 uint8_t(又名字符串)和布尔值很简单,因为它们不需要字节序处理 - 你可以将它们中的每一个作为单个字节逐字复制到数组中。 uint16_t你可以通过htons()转换为big-endian,并通过ntohs()转换回native-endian。浮点值有点棘手,因为没有内置的htonf(),但你可以自己动手,这将适用于符合IEEE754标准的机器:
uint32_t htonf(float f)
{
uint32_t x;
memcpy(&x, &f, sizeof(float));
return htonl(x);
}
....和相应的ntohf()来解压缩它们:
float ntohf(uint32_t nf)
{
float x;
nf = ntohl(nf);
memcpy(&x, &nf, sizeof(float));
return x;
}
最后对于字符串,您只需通过memcpy将字符串的字节添加到缓冲区(包括NUL终止符):
const char * s = "hello";
int slen = strlen(s);
memcpy(myByteArray, s, slen+1); // +1 for the NUL byte
答案 2 :(得分:1)
我也在寻找同样的事情。幸运的是我找到了https://github.com/mpapierski/struct
添加一些内容可以将缺少的类型添加到struct.hpp中,我认为它是迄今为止最好的。
要使用它,只需定义这样的参数
DEFINE_STRUCT(test,
((2, TYPE_UNSIGNED_INT))
((20, TYPE_CHAR))
((20, TYPE_CHAR))
)
刚刚调用此函数将在编译时生成
pack(unsigned int p1, unsigned int p2, const char * p3, const char * p4)
参数的数量和类型取决于您在上面定义的内容。 返回类型是char *,其中包含打包数据。 还有另一个unpack()函数可用于读取缓冲区
答案 3 :(得分:0)
您可以查看Boost.Serialization,但我怀疑您是否可以使用与Python包相同的格式。
答案 4 :(得分:-1)
您可以使用union
将不同的视图显示到同一内存中。
例如:
union Pack{
int i;
char c[sizeof(int)];
};
Pack p = {};
p.i = 1234;
std::string packed(p.c, sizeof(int)); // "\xd2\x04\x00\0"
如其他答案所述,您必须注意字节序。