位域的二进制"bulk"序列化
Binary "bulk" serialization of bitfields
我有很多布尔属性的对象,所以我使用位域来打包更紧凑的属性。我还希望能够以一种紧凑的方式序列化和反序列化这些属性,例如,不是逐个字段,而是通过序列化和反序列化保存字段的64位单元。这种方式不仅更快(例如,避免所有的移动和东西),而且内存效率提高了8倍。
然而,我读到这个标准并不能保证位场的实现在不同的平台上是统一的。我能期望位域容器的"批量"二进制序列化在不同平台上产生统一的结果吗?或者,在处理属性时,手动移动和屏蔽会更安全,以便可以进行批量序列化和反序列化?
您可以查看std::bitset:
它提供了定义良好的函数来将您的位转换为unsigned long类型,并从存储的unsigned long类型创建bitset类型。定义bitset的第一个位是ullong
表示的最低有效数字。
所以你可以这样写:
std::bitset<N> bits;
unsigned long long val = bits.to_ullong();
// serialize your ullong value
// load ullong from serialized data
unsigned long long val2 = ...;
std::bitset<N> newBits(val2);
所以,只要你的序列化可以正确加载/存储unsigned long long
,你就可以开始了。
唯一的问题是当你有一个位域太大的unsigned long long
。在这种情况下,标准没有提供提取位域的简单方法。
一种可能性是使用ASN.1通过BIT STRING来处理此问题。它以一种独立于本地表示的方式精确地定义序列化。这使得它可以跨平台保持一致,而不管本地平台是大端还是小端。您可以在http://asn1-playground.oss.com上使用免费的在线ASN.1编译器和编码器/解码器来查看结果序列化。
ASN。
平台端序的差异表明任何这样的序列化都是不可移植的。基于此,我想说,你不能指望位域容器的批量二进制序列化在不同平台上是统一的。
解决方案必须考虑位的顺序并根据平台进行校正。
这可能对您有所帮助,这是各种序列化类型的一个小示例。我添加了bitset和原始位值,可以像下面这样使用。
(所有示例见https://github.com/goblinhack/simple-c-plus-plus-serializer)
class BitsetClass {
public:
std::bitset<1> a;
std::bitset<2> b;
std::bitset<3> c;
unsigned int d:1; // need c++20 for default initializers for bitfields
unsigned int e:2;
unsigned int f:3;
BitsetClass(void) { d = 0; e = 0; f = 0; }
friend std::ostream& operator<<(std::ostream &out,
Bits<const class BitsetClass & > const m
{
out << bits(my.t.a);
out << bits(my.t.b);
out << bits(my.t.c);
std::bitset<6> s(my.t.d | my.t.e << 1 | my.t.f << 3);
out << bits(s);
return (out);
}
friend std::istream& operator>>(std::istream &in,
Bits<class BitsetClass &> my)
{
std::bitset<1> a;
in >> bits(a);
my.t.a = a;
in >> bits(my.t.b);
in >> bits(my.t.c);
std::bitset<6> s;
in >> bits(s);
unsigned long raw_bits = static_cast<unsigned long>(s.to_ulong());
my.t.d = raw_bits & 0b000001;
my.t.e = (raw_bits & 0b000110) >> 1;
my.t.f = (raw_bits & 0b111000) >> 3;
return (in);
}
};
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- 位域的二进制"bulk"序列化