1

使用 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 消失了?

4

1 回答 1

0

通过方法的一些改变,这个问题已经解决了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;

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

于 2020-06-16T06:38:19.770 回答