【发布时间】:2019-06-24 15:21:48
【问题描述】:
我们使用nanopb 库作为我们的协议缓冲区库。我们定义了以下消息:
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。
In the documentation for pb_encode() 它说:
[...] 但是,子消息必须被序列化两次:首先是 计算它们的大小,然后将它们实际写入输出。这 导致回调字段的一些约束,它必须返回 每次通话的数据相同。
但是,我们不确定如何解释这句话 - 究竟要遵循哪些步骤来实现这一点。
所以我们的问题是:
- 使用nanopb 库对包含固定大小(重复)子消息的消息进行编码的正确方法是什么?
谢谢!
【问题讨论】:
标签: c protocol-buffers nanopb