Как получить значения данных и тип данных из flatbuffer во время выполнения - PullRequest
0 голосов
/ 04 июля 2019

У меня есть схема flatbuffer, определенная следующим образом

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 голосов
/ 04 июля 2019

(удаленный предыдущий ответ теперь, когда вопрос прояснен).

FlatBuffers имеет 2 API: по умолчанию, эффективный, способ, которым FlatBuffers предназначался для использования API, и дополнительный «Object API», который выследует использовать только в случае особых потребностей.

В основном вы используете Object API, хотя вы пытаетесь получить доступ к объединению, как если бы это был базовый API.Как вы можете видеть из ошибки, req имеет тип std::unique_ptr<DaemonRequestT> (не DaemonRequest), который имеет data член типа PacketDataUnion, который в свою очередь имеет методы сопряжения, такие как AsStrParamPacket, который выполняет приведениедля вас (или верните nullptr, если неверный тип).

...