сообщение TestMessage {
необходимое int32 id = 1;
необязательное string name = 2;
}
./nanopb_test --test_data=test_data.pb --verbose
После запуска тестов nanopb_test, результаты будут отображены в консоли. Убедитесь, что все тесты прошли успешно и нет ошибок.
Эта инструкция предназначена для помощи в использовании nanopb_test для тестирования библиотеки nanopb.
В недавно разработанном проекте по работе с Bluetooth, было обнаружено, что на некоторых платформах объем доступной памяти очень мал. Использование protobuf-c для сериализации данных может быть ограничено из-за недостатка памяти.
Для языка C в среде embedded Nanopb является хорошим выбором для сериализации данных. Использование Nanopb также является относительно простым. Nanopb имеет унифицированный интерфейс для кодирования и декодирования данных (функции pb_encode
и pb_decode
). В отличие от этого, protobuf-c генерирует отдельные интерфейсы для кодирования и декодирования для каждого сообщения.# Скачивание и установка Nanopb
Ссылка для скачивания: https://jpa.kapsi.fi/nanopb/download/
Я скачал версию для Linux: nanopb-0.3.9.2-linux-x86.tar.gz
После того, как вы скачали и распаковали архив, следующие файлы будут использоваться для кодирования и декодирования данных:
pb_common.c
, pb_common.h
, pb_decode.c
, pb_decode.h
, pb_encode.c
, pb_encode.h
, pb.h
. Эти файлы следует поместить на платформу, на которой вы планируете использовать библиотеку.
UserInformation.proto
.syntax = "proto3";
option optimize_for = LITE_RUNTIME;
enum UserStatus {
UNKNOWN = 0;
IDLE = 1;
BUSY = 2;
}
```сообщение UserInformation {
string name = 1;
uint32 age = 2;
string phone = 3;
UserStatus stat = 4;
string email = 5;
}
.proto
файле опция optimize_for
:
опция optimize_for = LITE_RUNTIME;
optimize_for
является опцией на уровне файла. Protocol Buffer определяет три уровня оптимизации: SPEED/CODE_SIZE/LITE_RUNTIME
. По умолчанию используется SPEED
.
SPEED: указывает на высокую производительность выполнения сгенерированного кода, но при этом компилируемый код будет занимать больше места.
CODE_SIZE: противоположно SPEED, код выполняется медленнее, но компилируемый код занимает меньше места. Обычно используется на платформах с ограниченными ресурсами, таких как мобильные устройства.
LITE_RUNTIME: сгенерированный код выполняется быстро, при этом занимает очень мало места. Это достигается за счёт отказа от функции рефлексии, предоставляемой Protocol Buffer. Поэтому при линковке Protocol Buffer в C++ используется только libprotobuf-lite, а не libprotobuf. В Java достаточно включить protobuf-java-2.4.1-lite.jar, а не protobuf-java-2.4.1.jar.
Примечание: для опции LITE_MESSAGE, все сгенерированные сообщения будут наследовать от MessageLite, а не от Message.
Nanopb
не поддерживает динамическое определение типа string
, в то время как Protobuf-c
компилирует его как char *
. Однако Nanopb
всегда компилирует его как массив типа char
. Поэтому здесь необходимо определить UserInformation.options
:// *******************************
// *** UserInformation options ***
// *******************************
//
UserInformation.name max_size:20
UserInformation.phone max_size:16
UserInformation.email max_size:30
```# Компиляция .proto файла
- Команда для компиляции C кода: `. /generator-bin/protoc --nanopb_out=. /UserInformation.proto`
! [Здесь должна быть картинка](https://img-blog.csdnimg.cn/20190130162917628.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pIT05HQ0FJMDkwMQ==,size_16,color_FFFFFF,t_70)
- Команда для компиляции C++ кода: `. /generator-bin/protoc --cpp_out=. /UserInformation.proto`
! [Здесь должна быть картинка](https://img-blog.csdnimg.cn/20190130163147412.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1pIT05HQ0FJMDkwMQ==,size_16,color_FFFFFF,t_70)
# Тестовый пример кода
Упаковка данных пользователя, основные 4 шага:
- Определение и инициализация переменной `UserInformation userInfo`;
- Присвоение значений переменной `userInfo`;
- Использование `pb_ostream_from_buffer` для создания `pb_ostream_t`, который содержит адрес буфера для кодирования;
- Использование `pb_encode` для кодирования.
```c
static int pack_user_data(uint8_t *buffer)
{
// Инициализация структуры UserInformation;
UserInformation userInfo = UserInformation_init_zero;
// Инициализация буфера
memset(buffer, 0, DATA_BUFFER_SIZE);
}
``````c
strcpy(userInfo.name, "Benjamin");
userInfo.age = 18;
strcpy(userInfo.phone, "0755-12345678");
userInfo.stat = UserStatus_IDLE;
strcpy(userInfo.email, "ZhangSan@123.com");
// Кодирование данных userInfo
pb_ostream_t enc_stream;
enc_stream = pb_ostream_from_buffer(buffer, DATA_BUFFER_SIZE);
if (!pb_encode(&enc_stream, UserInformation_fields, &userInfo))
{
// Произошла ошибка кодирования
printf("pb encode error in %s [%s]\n", __func__, PB_GET_ERROR(&enc_stream));
return -1;
}
return enc_stream.bytes_written;
}
Распаковка данных пользователя включает в себя три основных шага:
UserInformation userInfo
;pb_istream_from_buffer
для создания pb_istream_t
, содержащего адрес буфера для декодирования;pb_decode
для декодирования.static int unpack_user_data(const uint8_t *buffer, size_t len)
{
UserInformation userInfo;
// Декодирование данных userInfo
pb_istream_t dec_stream;
dec_stream = pb_istream_from_buffer(buffer, len);
if (!pb_decode(&dec_stream, UserInformation_fields, &userInfo))
{
printf("pb decode error in %s\n", __func__);
return -1;
}
printf("Распаковка: %s %d %s %s\n", userInfo.name, userInfo.age, userInfo.phone, userInfo.email);
return 0;
}
Основная функция main для вызова
int main()
{
uint8_t buffer[DATA_BUFFER_SIZE];
int length = pack_user_data(buffer);
if(length < 0){
printf("main: pack_user_data failed!!!\n");
return -1;
}
printf("Длина данных пользователя: %d\n", length);
unpack_user_data(buffer, length);
return 0;
}
Результат выполнения программы:
адрес на gitee: https://gitee.com/dianqi0901zc/nanopb_test
Ссылка на блог: https://blog.csdn.net/ZHONGCAI0901/article/details/86705381
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )