美文网首页
[nanopb]与兼容protobuf-c改造

[nanopb]与兼容protobuf-c改造

作者: LittleFat | 来源:发表于2021-03-11 14:32 被阅读0次

    背景

    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
    ...
    

    使用

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

    相关文章

      网友评论

          本文标题:[nanopb]与兼容protobuf-c改造

          本文链接:https://www.haomeiwen.com/subject/ybonqltx.html