• protobuf c语言库 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
    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!

     

  • 相关阅读:
    【性能测试】ChaosTesting(混沌测试)&ChaosBlade(混沌实验工具)(四)-k8s容器混沌实验
    力扣刷题-字符串-反转字符串Ⅱ
    The IDE is running low on memory and this might affect performance.
    从 0 实现 logistic 回归
    产品经理学习路线
    【鸿蒙软件开发】ArkTS基础组件之TextClock(时间显示文本)、TextPicker(滑动选择文本)
    使用awescnb自定义博客园皮肤
    图片扫描仪第一弹,我实现了一个办公位简笔画
    day32贪心算法part02| 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II
    SSM整合
  • 原文地址:https://blog.csdn.net/oushaojun2/article/details/133088025