[nanopb]与兼容protobuf-c改造

背景

RTOS系统,使用protobuf-c-compiler生成的库比较大,为精简代码空间,找到了适合RTOS系统的nanopb

生成proto源码

1 定义一个消息tp.proto

syntax = "proto2";
package tp; 

message AuthBlock {
    enum METHOD {
        AUTH_MD5 = 0;
        AUTH_TOKEN = 1;
    }
    optional METHOD method = 1;
    optional bytes pri = 2;
}

message Auth {
    optional string name = 1;
    optional AuthBlock auth = 2;
}

message AuthAck {
     optional int32 result = 1 [default = 0];
}

2 生成源码

protoc --plugin=../generator/protoc-gen-nanopb --nanopb_out=./ tp.proto
生成结构如下:

/* Struct definitions */
typedef struct _tp__AuthAck {
    bool has_result;
    int32_t result;
/* @@protoc_insertion_point(struct:tp__AuthAck) */
} tp__AuthAck;

typedef struct _tp__AuthBlock {
    bool has_method;
    tp__AuthBlock__METHOD method;
    pb_callback_t pri;
/* @@protoc_insertion_point(struct:tp__AuthBlock) */
} tp__AuthBlock;

typedef struct _tp__Auth {
    pb_callback_t name;
    bool has_auth;
    tp__AuthBlock auth;
/* @@protoc_insertion_point(struct:tp__Auth) */
} tp__Auth;

pb_callback_t:WTF?

3 改善源码中的结构类型

类型为string,repeated,message等消息的,生成的结构类型为pb_callback_t,对于从protobuf-c转过来的人,使用应该表示不适应,可以这样改造,调整nanopb_generator.py文件中对于默认类型的转换:
···
class Field:
...

    # Decide how the field data will be allocated
    if field_options.type == nanopb_pb2.FT_DEFAULT:
        if can_be_static:
            field_options.type = nanopb_pb2.FT_STATIC
        else:
            field_options.type = nanopb_pb2.FT_POINTER #change DEFAULT nanopb_pb2.FT_CALLBACK to nanopb_pb2.FT_POINTER

···

重新生成源码:
···
/* Struct definitions /
typedef struct _tp__AuthAck {
bool has_result;
int32_t result;
/
@@protoc_insertion_point(struct:tp__AuthAck) */
} tp__AuthAck;

typedef struct _tp__AuthBlock {
bool has_method;
tp__AuthBlock__METHOD method;
pb_bytes_array_t pri;
/
@@protoc_insertion_point(struct:tp__AuthBlock) */
} tp__AuthBlock;

typedef struct _tp__Auth {
char name;
bool has_auth;
tp__AuthBlock auth;
/
@@protoc_insertion_point(struct:tp__Auth) */
} tp__Auth;
···

虽然还有另一种方式,就是添加对应协议的类型参数,这样也能达到效果。但是目测繁琐所以推荐使用, 新建tp.options文件:

tp.Auth.name type:FT_POINTER
tp.Auth.auth type:FT_POINTER
...

使用

按照官方示例自己根据需要做序列化和反序列化即可。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容