当前位置:   article > 正文

protobuf c语言库 Nanopb的使用方法_nanopb教程

nanopb教程

protobuf有个开源c库,叫做nanopb,可以实现对protobuf的加密和解密。

项目地址:

https://github.com/nanopb/nanopb

项目的主页写的很清楚,使用方法为编译.proto文件,然后把各个文件包含进工程就可以了。

To use the nanopb library, you need to do two things:

  1. Compile your .proto files for nanopb, using protoc.
  2. Include pb_encode.cpb_decode.c and pb_common.c in your project.

 例如,编译simple.proto

nanopb-0.4.7-windows-x86\generator-bin>nanopb_generator.exe simple.proto
Writing to simple.pb.h and simple.pb.c

 产生的simple.pb.h,simple.pb.c文件就是可以拷贝进工程的文件。再加上原本的库文件pb.h, pb_common.c/.h, pb_encode.c/.h, pb_decode.c/.h文件,就可以正常使用了。

对于.proto文件的格式,如下有个大概的例子:

// A very simple protocol definition, consisting of only
// one message.


syntax = "proto2";

import "nanopb.proto";

message SimpleMessage {
    required int32 lucky_number = 1;
    required float float_number = 2;
    required string name = 3 [(nanopb).max_size = 40];
    repeated bool num = 4  [(nanopb).max_count = 5];
    repeated int32 ids = 5  [(nanopb).max_count = 5];
    repeated int32 array = 6 [(nanopb).max_count = 5, (nanopb).int_size = IS_8];
}

产生的simple.pb.h文件如下,可以对比知道怎么编写各种类型的数据和数组:

  1. /* Automatically generated nanopb header */
  2. /* Generated by nanopb-0.4.7 */
  3. #ifndef PB_SIMPLE_PB_H_INCLUDED
  4. #define PB_SIMPLE_PB_H_INCLUDED
  5. #include <pb.h>
  6. #if PB_PROTO_HEADER_VERSION != 40
  7. #error Regenerate this file with the current version of nanopb generator.
  8. #endif
  9. /* Struct definitions */
  10. typedef struct _SimpleMessage {
  11. int32_t lucky_number;
  12. float float_number;
  13. char name[40];
  14. pb_size_t num_count;
  15. bool num[5];
  16. pb_size_t ids_count;
  17. int32_t ids[5];
  18. pb_size_t array_count;
  19. int8_t array[5];
  20. } SimpleMessage;
  21. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. /* Initializer values for message structs */
  25. #define SimpleMessage_init_default {0, 0, "", 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}}
  26. #define SimpleMessage_init_zero {0, 0, "", 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}}
  27. /* Field tags (for use in manual encoding/decoding) */
  28. #define SimpleMessage_lucky_number_tag 1
  29. #define SimpleMessage_float_number_tag 2
  30. #define SimpleMessage_name_tag 3
  31. #define SimpleMessage_num_tag 4
  32. #define SimpleMessage_ids_tag 5
  33. #define SimpleMessage_array_tag 6
  34. /* Struct field encoding specification for nanopb */
  35. #define SimpleMessage_FIELDLIST(X, a) \
  36. X(a, STATIC, REQUIRED, INT32, lucky_number, 1) \
  37. X(a, STATIC, REQUIRED, FLOAT, float_number, 2) \
  38. X(a, STATIC, REQUIRED, STRING, name, 3) \
  39. X(a, STATIC, REPEATED, BOOL, num, 4) \
  40. X(a, STATIC, REPEATED, INT32, ids, 5) \
  41. X(a, STATIC, REPEATED, INT32, array, 6)
  42. #define SimpleMessage_CALLBACK NULL
  43. #define SimpleMessage_DEFAULT NULL
  44. extern const pb_msgdesc_t SimpleMessage_msg;
  45. /* Defines for backwards compatibility with code written before nanopb-0.4.0 */
  46. #define SimpleMessage_fields &SimpleMessage_msg
  47. /* Maximum encoded size of messages (where known) */
  48. #define SimpleMessage_size 177
  49. #ifdef __cplusplus
  50. } /* extern "C" */
  51. #endif
  52. #endif

用vc写个测试程序:

  1. // protobuf_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include "stdio.h"
  4. #include "pb_encode.h"
  5. #include "pb_decode.h"
  6. #include "simple.pb.h"
  7. int main(void)
  8. {
  9. uint8_t buffer[128];
  10. size_t message_length;
  11. bool status;
  12. {
  13. SimpleMessage message = SimpleMessage_init_zero;
  14. pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
  15. message.lucky_number = 13;
  16. status = pb_encode(&stream, SimpleMessage_fields, &message);
  17. message_length = stream.bytes_written;
  18. if (!status)
  19. {
  20. printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
  21. return 1;
  22. }
  23. else
  24. {
  25. printf("encode protobuf ok, len=%d\r\n", message_length);
  26. }
  27. }
  28. {
  29. SimpleMessage message = SimpleMessage_init_zero;
  30. pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
  31. status = pb_decode(&stream, SimpleMessage_fields, &message);
  32. if (!status)
  33. {
  34. printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
  35. return 1;
  36. }
  37. else
  38. {
  39. printf("Your lucky number was %d!\n", (int)message.lucky_number);
  40. }
  41. }
  42. return 0;
  43. }

输出为:

encode protobuf ok, len=2
Your lucky number was 13!

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/901801
推荐阅读
相关标签
  

闽ICP备14008679号