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文件如下,可以对比知道怎么编写各种类型的数据和数组:

/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.7 */

#ifndef PB_SIMPLE_PB_H_INCLUDED
#define PB_SIMPLE_PB_H_INCLUDED
#include <pb.h>

#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif

/* Struct definitions */
typedef struct _SimpleMessage {
    int32_t lucky_number;
    float float_number;
    char name[40];
    pb_size_t num_count;
    bool num[5];
    pb_size_t ids_count;
    int32_t ids[5];
    pb_size_t array_count;
    int8_t array[5];
} SimpleMessage;


#ifdef __cplusplus
extern "C" {
#endif

/* Initializer values for message structs */
#define SimpleMessage_init_default               {0, 0, "", 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}}
#define SimpleMessage_init_zero                  {0, 0, "", 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0}}

/* Field tags (for use in manual encoding/decoding) */
#define SimpleMessage_lucky_number_tag           1
#define SimpleMessage_float_number_tag           2
#define SimpleMessage_name_tag                   3
#define SimpleMessage_num_tag                    4
#define SimpleMessage_ids_tag                    5
#define SimpleMessage_array_tag                  6

/* Struct field encoding specification for nanopb */
#define SimpleMessage_FIELDLIST(X, a) \
X(a, STATIC,   REQUIRED, INT32,    lucky_number,      1) \
X(a, STATIC,   REQUIRED, FLOAT,    float_number,      2) \
X(a, STATIC,   REQUIRED, STRING,   name,              3) \
X(a, STATIC,   REPEATED, BOOL,     num,               4) \
X(a, STATIC,   REPEATED, INT32,    ids,               5) \
X(a, STATIC,   REPEATED, INT32,    array,             6)
#define SimpleMessage_CALLBACK NULL
#define SimpleMessage_DEFAULT NULL

extern const pb_msgdesc_t SimpleMessage_msg;

/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define SimpleMessage_fields &SimpleMessage_msg

/* Maximum encoded size of messages (where known) */
#define SimpleMessage_size                       177

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif

用vc写个测试程序:

// protobuf_test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "stdio.h"

#include "pb_encode.h"
#include "pb_decode.h"
#include "simple.pb.h"

int main(void)
{
    uint8_t buffer[128];
    size_t message_length;
    bool status;

    {
        SimpleMessage message = SimpleMessage_init_zero;

        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));

        message.lucky_number = 13;

        status = pb_encode(&stream, SimpleMessage_fields, &message);
        message_length = stream.bytes_written;
        if (!status)
        {
            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }
        else
        {
            printf("encode protobuf ok, len=%d\r\n", message_length);
        }
    }

    {
        SimpleMessage message = SimpleMessage_init_zero;

        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);

        status = pb_decode(&stream, SimpleMessage_fields, &message);
        if (!status)
        {
            printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
            return 1;
        }
        else
        {
            printf("Your lucky number was %d!\n", (int)message.lucky_number);
        }
    }

    return 0;
}

输出为:

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

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐