Является ли префикс размера для каждого буфера или всей программы?

Я передаю плоские буферы по сети, поэтому каждый буфер имеет префикс размера FinishSizePrefixedFoo(fbb, msg), но я заметил, что этот префикс размера не является размером структуры сообщения msg, это размер всего построителя буфера. Например:

flatbuffers::FlatBufferBuilder fbb;
flatbuffers::Offset<Message> msg;
msg = sge::sgedm::CreateMessage(fbb, ...);
FinishSizePrefixedMessageBuffer(fbb, msg);
flatbuffers::uoffset_t len = flatbuffers::ReadScalar<flatbuffers::uoffset_t>(fbb.GetBufferPointer());
std::cout << "Buffer size is " << fbb.GetSize() << " size prefix is " << len << std::endl;
flatbuffers::Offset<Message> msg2;
msg2 = sge::sgedm::CreateMessage(fbb, ...);
FinishSizePrefixedMessageBuffer(fbb, msg2);
len = flatbuffers::ReadScalar<flatbuffers::uoffset_t>(fbb.GetBufferPointer());
std::cout << "Buffer size is " << fbb.GetSize() << " size prefix is " << len << std::endl;

Результат:

Buffer size is 84 size prefix is 80
Buffer size is 168 size prefix is 164

Но ожидаемый результат:

Buffer size is 84 size prefix is 80
Buffer size is 168 size prefix is 80

В противном случае нет возможности разделить два сообщения.

Я использую этот префикс размера для проверки и десериализации, например:

buf[4] = recv(4);
uoffset_t len = ReadScalar(buf);
buf[4..len+4] = recv(len);
msg = GetSizePrefixedMessage(buf);

Когда я читаю, что размер равен 164, ожидается, что последует сообщение размером 164, хотя на самом деле это два сообщения по 80 байт каждое. Это ошибка плоских буферов?


person fluter    schedule 11.04.2019    source источник


Ответы (1)


Пожалуйста, убедитесь, что вы разрабатываете с включенными утверждениями, так как это уже сказало бы вам, что приведенный выше код неверен.

Когда вы вызываете Finish для построителя, вы не можете сериализовать в него больше данных, если вы не вызываете Clear. Так что в этом случае второй буфер также содержит копию первого буфера. Утверждение сказало бы вам это.

Конечно, вы также можете использовать 2 экземпляра FlatBufferBuilder, если хотите, чтобы оба буфера были доступны.

person Aardappel    schedule 11.04.2019
comment
Я включил #define FLATBUFFERS_ASSERT, никаких проблем не сообщается. - person fluter; 12.04.2019
comment
Нет, вы должны убедиться, что тестируете в режиме отладки на своей платформе. Каждый компилятор C/C++ на каждой платформе остановится при сбое assert() вызовов. Вы их почему-то не получаете. - person Aardappel; 13.04.2019
comment
Просто утверждение не срабатывает. Я не нахожу в документах ссылок на то, что Finish предназначен для всего компоновщика, я думаю, что это означает завершение текущего буфера. - person fluter; 13.04.2019
comment
Да, они не попадают, потому что вы компилируете в режиме выпуска или какой-то другой параметр компилятора, который их отключает. - person Aardappel; 13.04.2019
comment
А билдер держит один буфер. - person Aardappel; 13.04.2019
comment
любые ссылки для этого? - person fluter; 14.04.2019