如何在运行时从FlatBuffer获取数据值和数据类型

时间:2019-07-04 13:12:37

标签: c++ flatbuffers

我有一个像这样定义的平面缓冲区架构

enum Payload : uint8 { BLOB, STRPARAM } //type of payload

table Header
{
    payload: Payload;
    sender: string;
    module: string;
    command: string;
    parameter: string;
    timestamp: string; 
    status: string; // used for reply from Daemon: success or fail
    message: string; // Status message, to get more info when request fails
}

table BlobPacket
{
    value: [byte];
}

table StrParamPacket
{
    value1: string; // e.g. "4"
    value2: string; // e.g. "5.7"
}

union PacketData 
{
    BlobPacket, StrParamPacket
}

table DaemonRequest
{   
    header:Header; //Tells information about the packet
    data:PacketData; //Actual data
}

root_type DaemonRequest;

使用以下代码将其打包为请求

    flatbuffers::FlatBufferBuilder* _builder = nullptr;

    DaemonRequestT request;
    HeaderT header;
    BlobPacketT blobPacket;
    StrParamPacketT strParamPacket;

    header.payload = 0;//str param
    header.sender = sender;
    header.module = module;
    header.command = command;
    header.parameter = parameter;

    auto headerOffset = CreateHeader(*_builder, &header);

    strParamPacket.value1 = value1;
    strParamPacket.value2 = value2;

    auto strParamPacketOffset = CreateStrParamPacket(*_builder, &strParamPacket);

    auto req = CreateDaemonRequest(*_builder, &header, PacketData::StrParamPacket, strParamPacketOffset.Union());

此请求然后发送到服务器,服务器将请求打包 使用

auto req= UnPackDaemonRequest(receivedBuffer);

通过此请求,我可以使用req->header->command之类的命令获取标头详细信息。 但是我在获取联合表的data_type和数据时遇到问题。

我尝试按照flatbuffer教程进行操作,但是没有太多文档说明如何在解压缩后获取数据。 生成的文件->“ https://pastebin.com/zLEyd8BE”(使用--gen-object-api --scoped-enums --cpp)

我尝试使用此方法获取数据

    auto union_type = req.data_type(); //error
    if (union_type == PacketData::StrParamPacket) 
    {
        auto strParamPacket = static_cast<const StrParamPacket*>(req->data());//error
        auto command = req->header->command; //std::sting
        auto parameter = req->header->parameter; //std::string
        auto message = req.get()->header->message; //std::string&
        auto value1 = strParamPacket.get()->value1; //std::string&
        auto value2 = strParamPacket.get()->value2; //std::string&
    }

这会导致以下错误

: error: ‘class std::unique_ptr<DaemonRequestT>’ has no member named ‘data_type’; did you mean ‘deleter_type’?
     auto union_type = req.data_type(); //error
                           ^~~~~~~~~
                           deleter_type
../Daemon/Daemon.cpp:155:76: error: no match for call to ‘(PacketDataUnion) ()’
         auto strParamPacket = static_cast<const StrParamPacket*>(req->data());//error

1 个答案:

答案 0 :(得分:0)

(现在已经澄清了该问题,删除了以前的答案)。

FlatBuffers有2个API:默认,高效,FlatBuffers应使用的API的方式,以及仅在有特殊需要时才应使用的可选“对象API”。

大多数情况下,您都在使用对象API,尽管您试图像它是基本API一样访问联合。从错误中可以看出,req的类型为std::unique_ptr<DaemonRequestT>(不是DaemonRequest),其成员类型为data的{​​{1}},而该成员具有诸如PacketDataUnion之类的便捷方法为您执行强制转换(如果类型错误,则返回nullptr)。