nanopb (библиотека Protocol Buffers) кодирует повторяющиеся под-сообщения - PullRequest
0 голосов
/ 24 июня 2019

мы используем библиотеку 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 ?

Спасибо!

1 Ответ

1 голос
/ 25 июня 2019

Вы не используете поля обратного вызова здесь, так что цитата не имеет значения для вас. Но если бы вы были, это просто означало бы, что в некоторых ситуациях ваш обратный вызов будет вызываться несколько раз.

Вы тот же человек, что и на форуме ? Ваш вопрос переполнения стека не показывает его, но у человека на форуме есть похожая проблема, которая, по-видимому, связана с не установкой vector_count. Тогда он останется массивом 0 длины. Поэтому попробуйте добавить:

message.vector_count = 300;

В будущем, пожалуйста, подождите несколько дней, прежде чем публиковать один и тот же вопрос в нескольких местах. Бесполезно тратить время на то, чтобы ответить на один и тот же вопрос несколько раз.

...