Я хочу избежать функций Pb_callback, возникающих при использовании «повторяющихся» полей в .proto
Обратите внимание, что вы можете указать max_count
для повторяющихся полей, как вы указалиmax_size
для строк, и вместо обратного вызова вы получите простой массив.
Хотя, если я разделю его на 2 сообщения, я не смогу десериализовать их за один раз с однимфайл прото.
Для десериализации Protobuf необходимо знать тип сообщения. Наиболее распространенный способ справиться с этим - создать одно сообщение верхнего уровня с вложенными сообщениями:
message LogMessage {
optional LogHeader header = 1;
optional Sensors sensors = 2;
}
Затем вы можете установить одно или оба поля заголовка и датчика, а также has_header
и has_sensors
в true или false, чтобы указать, хотите ли вы включить это подполе. Но независимо от содержимого, вы всегда сериализуете и десериализуете как LogMessage
, так что нет никакой путаницы между различными типами сообщений.
Мне нужно знать длину первых двух сообщений, десериализоватьих, а затем начинайте с лога.
Да, это обычная проблема для новичков и с protobuf. Сами сообщения Protobuf не кодируют их длину, поэтому, если у вас есть несколько сообщений в одном файле, вам нужно как-то их разделить.
A весьма распространенный способ - добавить префикс длины, так каксделано наноппами pb_encode_delimited()
и pb_decode_delimited()
. Этот формат также поддерживается библиотекой C ++ protobuf. Однако недостатком этого является то, что многие инструменты командной строки, такие как protoc
, не поддерживают формат с разделителями, и, например, библиотека Python protobuf делает их декодирование несколько сложным .
Другой вариант заключается всделать так, чтобы весь файл выглядел так, как будто это было одно сообщение, но пишите его несколькими частями. Протобуфы имеют функцию слияния, то есть, если вы просто добавляете сообщения друг за другом, они объединяются вместе. Это можно сделать, включив повторяющиеся поля в LogMessage
:
message LogMessage {
optional LogHeader header = 1;
repeated Sensors sensors = 2 [(nanopb).max_count = 1];
}
Теперь, если вы закодируете несколько копий LogMessage
, каждая с одной записью sensors
, они объединятся. Затем, если вы декодируете файл, он будет выглядеть как один LogMessage
с несколькими sensors
записями.