nanopb (Protocol Buffers library) 重复的子消息编码

nanopb (Protocol Buffers library) repeated sub-messages encode

我们使用 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,因此将其定义为 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.

In the documentation 对于 pb_encode() 它说:

[...] However, submessages must be serialized twice: first to calculate their size and then to actually write them to output. This causes some constraints for callback fields, which must return the same data on every call.

但是,我们不确定如何解释这句话——具体要遵循哪些步骤才能实现这一目标。

所以我们的问题是:

谢谢!

您没有在此处使用回调字段,因此该报价对您来说无关紧要。但如果你是,那只意味着在某些情况下你的回调会被多次调用。

你和on the forum是同一个人吗?你的堆栈溢出问题没有显示出来,但是论坛上的人有类似的问题,似乎是由于没有设置vector_count。然后它将保持为 0 长度数组。所以尝试添加:

message.vector_count = 300;

以后同一个问题多发帖请稍等几天。多次回答同一个问题是浪费志愿者时间。