мы используем библиотеку nanopb в качестве нашей библиотеки Protocol Buffers. Мы определили следующие сообщения:
simple.proto
:
syntax = "proto2";
message repField {
required float x = 1;
required float y = 2;
required float z = 3;
}
message SimpleMessage {
required float lucky_number = 1;
repeated repField vector = 2;
}
с simple.options
SimpleMessage.vector max_count:300
Итак, мы знаем, что repField
имеет фиксированный размер 300 и поэтому определяет его как таковой.
Части сгенерированного выглядят так:
simple.pb.c
const pb_field_t repField_fields[4] = {
PB_FIELD( 1, FLOAT , REQUIRED, STATIC , FIRST, repField, x, x, 0),
PB_FIELD( 2, FLOAT , REQUIRED, STATIC , OTHER, repField, y, x, 0),
PB_FIELD( 3, FLOAT , REQUIRED, STATIC , OTHER, repField, z, y, 0),
PB_LAST_FIELD
};
const pb_field_t SimpleMessage_fields[3] = {
PB_FIELD( 1, FLOAT , REQUIRED, STATIC , FIRST, SimpleMessage, lucky_number, lucky_number, 0),
PB_FIELD( 2, MESSAGE , REPEATED, STATIC , OTHER, SimpleMessage, vector, lucky_number, &repField_fields),
PB_LAST_FIELD
};
и часть simple.pb.h
:
/* Struct definitions */
typedef struct _repField {
float x;
float y;
float z;
/* @@protoc_insertion_point(struct:repField) */
} repField;
typedef struct _SimpleMessage {
float lucky_number;
pb_size_t vector_count;
repField vector[300];
/* @@protoc_insertion_point(struct:SimpleMessage) */
} SimpleMessage;
Мы пытаемся закодировать сообщение, выполнив:
// Init message
SimpleMessage message = SimpleMessage_init_zero;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
// Fill in message
[...]
// Encode message
status = pb_encode(&stream, SimpleMessage_fields, &message);
// stream.bytes_written is wrong!
Но stream.bytes_written
неправильный, что означает, что он не закодирован правильно, хотя status=1
.
В документации для pb_encode()
написано:
[...] Однако, суб-сообщения должны быть сериализованы дважды: сначала
рассчитать их размер, а затем на самом деле записать их на выход. это
вызывает некоторые ограничения для полей обратного вызова, которые должны возвращать
одни и те же данные при каждом вызове.
Но мы не уверены, как интерпретировать это предложение - какие именно шаги следует выполнить для достижения этого.
Итак, наш вопрос:
- Как правильно кодировать сообщения, которые содержат (повторяющиеся) суб-сообщения фиксированного размера, используя библиотеку nanopb ?
Спасибо!