为什么 Glib::VariantBase::store 方法破坏了给定缓冲区的开始



使用Glib::VariantBase的乐趣可能是无价的。但也带来了许多障碍。我很难理解为什么非常基本的 Glib::VariantBase::store 方法正在更改我的缓冲区的开始。

请假设我分配了一个足够的缓冲区,最好写下来:

my_beautiful_buffer = static_cast<char*>(std::malloc(1024));

然后我想在其开头添加一个uint64_t变量:

uint64_t my_humble_var = 1;
*reinterpret_cast<uint64_t*>(my_beautiful_buffer) = my_humble_var;

让我们使用 printf 读取缓冲区

for (int i = 0; i < 8; i++) printf("0x%x ", *(unsigned char*)(my_beautiful_buffer+i));
+++++++++my_beautiful_buffer+++
0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0

让我们创建一个相当复杂的 GlibVariable

using myStrangeVarType = Glib::Variant<std::map<Glib::ustring,std::map<Glib::ustring, std::tuple<Glib::VariantBase, std::uint64_t>>>>
myStrangeVarType data = createData(); // createData method statically defines variable and and copies

现在让我们存储这个新创建的变量

data.store((my_beautiful_buffer + sizeof(std::uint64_t)));

我们可以读取我们美丽的缓冲区中的所有数据吗

for (int i = 0; i < data.get_size() + sizeof(std::uint64_t); i++) printf("0x%x ", *(unsigned char*)(m_buffer+i));
+++++++++Data Written+++++++
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x61 0x70 0x70 0x49 0x64 0x31 0x2f 0x64 0x61 0x74 0x61 0x62
0x61 0x73 0x65 0x31 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x6b 0x65 0x79 0x31 0x0 0x0 0x0 0x0 0x73
0x74 0x72 0x69 0x6e 0x67 0x20 0x76 0x61 0x6c 0x75 0x65 0x0 0x0 0x73 0x0 0x62 0x67 0xbc 0x0 0x0
0x0 0x0 0x0 0xf 0x5 0x0 0x0 0x0 0x0 0x0 0x0 0x6b 0x65 0x79 0x32 0x0 0x0 0x0 0x0 0xd2 0x4 0x0
0x6e 0x0 0x0 0x0 0x0 0x62 0x67 0xbc 0x0 0x0 0x0 0x0 0x0 0x4 0x5 0x22 0x42 0x11 0x0

好的,在这一点上,我的前 8 个字节发生了什么,为什么第一个字节0x1消失了?

这个问题已经通过createData方法的一些更改得到解决。 该方法是生成具有a{sa{s(vt)}}类型的Glib::VariantBase,显然打包和解包自定义类型并不是Glib::Variant的真正强项。

我必须将我的对象转换为v类型。问题已解决。 这就是我更改类型的方式:

GVariant* gVariant = g_variant_new("v", value.gobj());
Glib::VariantBase variantValue = Glib::VariantBase(gVariant);
return variantValue;

早些时候,我只是返回值而不进行任何这些转换。


解决问题的另一种方法是调用value.get_size();并在之后返回它。

value.get_size();
return value;

显然,该调用在内部会导致变体被序列化。

最新更新