You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用FlatBuffers序列化对象向量出现数据异常的原因

问题原因及解决方案

这个问题的核心是你混淆了FlatBuffers中struct值类型table引用类型的内存处理逻辑,以及CreatePlumbusesTableDirect函数对struct数组参数的要求。

为什么会出现垃圾值?

FlatBuffers里的struct内联存储的轻量类型——序列化时会直接把struct的所有字段值复制到FlatBuffer缓冲区中,不需要额外的偏移或引用。而生成的CreatePlumbusesTableDirect函数,针对你的Schema里的plumbuses:[Plumbus](struct数组)参数,实际期望的是const std::vector<Plumbus>*类型(即struct值的集合),但你传入的是const std::vector<const Plumbus*>*(struct指针的集合)。

当FlatBuffers接收到指针数组时,会错误地把这些指针的内存地址值当成struct的二进制数据来解析,自然就输出了毫无意义的垃圾值。

修复代码的正确姿势

你不需要创建指针数组pbPtrs,直接传入原始的std::vector<Plumbus>即可。以下是完整的示例代码:

序列化部分

#include "plumbus_generated.h"
#include <flatbuffers/flatbuffers.h>
#include <vector>
#include <iostream>

using namespace rpc;

int main() {
    // 构造Plumbus值的向量
    std::vector<Plumbus> pbs;
    pbs.emplace_back(Plumbus{1, 2.0});
    pbs.emplace_back(Plumbus{3, 4.0});

    flatbuffers::FlatBufferBuilder builder;
    // 直接传入Plumbus值的vector指针
    auto plumbuses_table = CreatePlumbusesTableDirect(builder, &pbs);
    builder.Finish(plumbuses_table);

    // 保存或发送缓冲区...

解析部分

// 解析缓冲区(这里直接用当前builder的缓冲区做测试)
    const auto root = GetPlumbusesTable(builder.GetBufferPointer());
    const auto plumbuses = root->plumbuses();

    for (size_t i = 0; i < plumbuses->size(); ++i) {
        const auto& pb = plumbuses->Get(i);
        std::cout << "dinglebopBatch = " << pb.dinglebopBatch << ", fleeb = " << pb.fleeb << std::endl;
    }

    return 0;
}

额外补充:struct vs table的区别

  • struct:值类型,无虚表、无偏移,所有字段直接内联在父结构中,适合小的、不变的数据结构。序列化时传递值集合即可。
  • table:引用类型,有偏移量,序列化时需要先创建每个table的偏移,再传递指针集合(这也是你误以为可以传指针数组的原因,但struct不适用这个逻辑)。

内容的提问来源于stack exchange,提问作者nnnmmm

火山引擎 最新活动