本文在Aworks上使用nanopb库对string类型字段进行封包及解包测试。
参考链接封包及解包原理:https://www.cnblogs.com/silvermagic/p/9087593.html
message LaneStatus {
bool showLane = 1;
string laneBackInfo = 2;
string laneSelectInfo = 3;
}
使用如下命令进行编译
..\..\generator-bin\protoc --nanopb_out=. simple.proto
最终生成的结构体
/* Struct definitions */
typedef struct _LaneStatus {
bool showLane; /* true:显示/ false:隐藏 */
pb_callback_t laneBackInfo; /* 车道背景信息 */
pb_callback_t laneSelectInfo; /* 车道前景信息 */
} LaneStatus;
#include <stdio.h>
#include <pb_encode.h>
#include <pb_decode.h>
#include <string.h>
#include "BleMessage2.pb.h"
#include "aw_vdebug.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pb_decode.h>
#define TEST(x) if (!(x)) { \
aw_kprintf("Test %s failed (in field %d).\n", #x, field->tag); \
return false; \
}
static bool write_string(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
return pb_encode_tag_for_field(stream, field) &&
pb_encode_string(stream, *arg, strlen(*arg));
}
static bool read_string(pb_istream_t *stream, const pb_field_t *field, void **arg)
{
uint8_t buf[128] = {0};
size_t len = stream->bytes_left;
if (len > sizeof(buf) - 1 || !pb_read(stream, buf, len))
return false;
strncpy(*arg,(char *)buf,strlen(buf));
//TEST(strcmp((char*)buf, *arg) == 0);
return true;
}
int lanestatus_test_main()
{
/* This is the buffer where we will store our message. */
uint8_t buffer[128] = {0};
size_t message_length = 0;
bool status;
{
com_bst_modules_iot_proto_LaneStatus sign = com_bst_modules_iot_proto_LaneStatus_init_zero;
sign.laneBackInfo.funcs.encode = write_string;
sign.laneBackInfo.arg = &"laneBackInfo";
sign.laneSelectInfo.funcs.encode = write_string;
sign.laneSelectInfo.arg = &"laneSelectInfo";
sign.showLane = true;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
status = pb_encode(&stream, com_bst_modules_iot_proto_LaneStatus_fields, &sign);
message_length = stream.bytes_written;
/* Then just check for any errors.. */
if (!status) {
aw_kprintf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
return 1;
}
aw_kprintf("message_length: %d\n", message_length);
}
{
char laneBackInfo_tmp[128]={0};
char laneSelectInfo_tmp[128]={0};
/* Allocate space for the decoded message. */
com_bst_modules_iot_proto_LaneStatus message = com_bst_modules_iot_proto_LaneStatus_init_zero;
message.laneBackInfo.funcs.decode = read_string;
message.laneBackInfo.arg = &laneBackInfo_tmp;
message.laneSelectInfo.funcs.decode = read_string;
message.laneSelectInfo.arg = &laneSelectInfo_tmp;
/* Create a stream that reads from the buffer. */
pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
/* Now we are ready to decode the message. */
status = pb_decode(&stream, com_bst_modules_iot_proto_LaneStatus_fields, &message);
/* Check for errors... */
if (!status)
{
aw_kprintf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
return 1;
}
/* Print the data contained in the message. */
aw_kprintf("Your showLane = %d!\n", message.showLane);
aw_kprintf("Your laneBackInfo = %s!\n", laneBackInfo_tmp);
aw_kprintf("Your laneSelectInfo = %s!\n", laneSelectInfo_tmp);
aw_kprintf("Your laneBackInfo = %s!\n", message.laneBackInfo.arg);
aw_kprintf("Your laneSelectInfo = %s!\n", message.laneSelectInfo.arg);
}
}
AWorks for i.MX RT1050, build Mar 1 2022
AWorks SDK Version is 2.1.2 <2020-09-30>
current time: 1970-01-01 07:36:47
Appl|AWorks->>> ication Start.
message_length: 32
Your showLane = 1!
Your laneBackInfo = laneBackInfo!
Your laneSelectInfo = laneSelectInfo!
Your laneBackInfo = laneBackInfo!
Your laneSelectInfo = laneSelectInfo!
动态长度在封包及解包时,需要注册encode及decode函数,并且需要传递缓冲区。
动态长度也有一个弊端,比如Java开发者就不需要考虑长度,但是C语言开发者就需要考虑,最好的方式就是在双方约定最大长度大小。