zoukankan      html  css  js  c++  java
  • protobuf-c的学习总结

    1、前言

             项目中用到protobuf-c进行数据序列化,好处在于后期程序扩展性非常好,只需要改动proto的定义就可以保持兼容,非常的灵活方便。关于protobuf-c的详细介绍可以参考google官方文档。https://code.google.com/p/protobuf-c/。在此简单的介绍一下基本功能。proto文件格式如下所示:

    message AMessage
    {
         requried  int32  a = 1;  //a必须出现
         optional  string b = 2;  //b是可选的
         repeated  int32  c = 3;  //c是数组
    }

    字段规则类型:

    required:表示后面的数据是必须的。

    optional:表示后面数据是可选的。

    repeated:表示后面的数据是一个数组。

    标量数值类型

    .proto类型

    Java 类型

    C++类型

    备注

    double

    double

    double

     

    float

    float

    float

     

    int32

    int

    int32

    使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint32。

    int64

    long

    int64

    使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint64。

    uint32

    int[1]

    uint32

    Uses variable-length encoding.

    uint64

    long[1] uint64 Uses variable-length encoding.

    sint32

    int

    int32

    使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。

    sint64

    long

    int64

    使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。

    fixed32

    int[1]

    uint32

    总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。

    fixed64

    long[1]

    uint64

    总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。

    sfixed32

    int

    int32

    总是4个字节。

    sfixed64

    long

    int64

    总是8个字节。

    bool

    boolean

    bool

     

    string

    String

    string

    一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。

    bytes

    ByteString

    string

    可能包含任意顺序的字节数据。

    2、测试程序

      编写一个学生信息的proto,proto文件内容如下所示:

      1 message Student
      2 {
      3     required string id = 1;
      4     required string name = 2;
      5     required string gender = 3;
      6     required int32  age = 4;
      7     required string object = 5;
      8     required string home_address = 6;
      9     required string phone = 7;
     10 }

    编译命令: protoc-c --c_cout=.  student.proto

    生成student.pb-c.c 和 student.pb-c.h两个文件。student.pb-c.h文件内容如下所示:

     1 /* Generated by the protocol buffer compiler.  DO NOT EDIT! */
     2 
     3 #ifndef PROTOBUF_C_student_2eproto__INCLUDED
     4 #define PROTOBUF_C_student_2eproto__INCLUDED
     5 
     6 #include <google/protobuf-c/protobuf-c.h>
     7 
     8 PROTOBUF_C_BEGIN_DECLS
     9 
    10 
    11 typedef struct _Student Student;
    12 
    13 
    14 /* --- enums --- */
    15 
    16 
    17 /* --- messages --- */
    18 
    19 struct  _Student
    20 {
    21   ProtobufCMessage base;
    22   char *id;
    23   char *name;
    24   char *gender;
    25   int32_t age;
    26   char *object;
    27   char *home_address;
    28   char *phone;
    29 };
    30 #define STUDENT__INIT 
    31  { PROTOBUF_C_MESSAGE_INIT (&student__descriptor) 
    32     , NULL, NULL, NULL, 0, NULL, NULL, NULL }
    33 
    34 
    35 /* Student methods */
    36 void   student__init
    37                      (Student         *message);
    38 size_t student__get_packed_size
    39                      (const Student   *message);
    40 size_t student__pack
    41                      (const Student   *message,
    42                       uint8_t             *out);
    43 size_t student__pack_to_buffer
    44                      (const Student   *message,
    45                       ProtobufCBuffer     *buffer);
    46 Student *
    47        student__unpack
    48                      (ProtobufCAllocator  *allocator,
    49                       size_t               len,
    50                       const uint8_t       *data);
    51 void   student__free_unpacked
    52                      (Student *message,
    53                       ProtobufCAllocator *allocator);
    54 /* --- per-message closures --- */
    55 
    56 typedef void (*Student_Closure)
    57                  (const Student *message,
    58                   void *closure_data);
    59 
    60 /* --- services --- */
    61 
    62 
    63 /* --- descriptors --- */
    64 
    65 extern const ProtobufCMessageDescriptor student__descriptor;
    66 
    67 PROTOBUF_C_END_DECLS
    68 
    69 
    70 #endif  /* PROTOBUF_student_2eproto__INCLUDED */

    测试proto程序如下所示:

      1 #include <stdio.h>
      2 #include <errno.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include "student.pb-c.h"
      6 
      7 #define ID_LEN         11
      8 #define NAME_LEN       32
      9 #define GENDER_LEN     10
     10 #define OBJECT_LEN     20
     11 #define HOME_ADDR_LEN  96
     12 #define PHONE_LEN      12
     13 
     14 static int malloc_student_info(Student *stu)
     15 {
     16     stu->id = (char*)malloc(ID_LEN);
     17     if (!stu->id)
     18     {
     19     goto FAILED;
     20     }
     21     stu->name = (char*)malloc(NAME_LEN);
     22     if (!stu->name)
     23     {
     24     goto FAILED;
     25     }
     26     stu->gender = (char*)malloc(GENDER_LEN);
     27     if (!stu->gender)
     28     {
     29     goto FAILED;
     30     }
     31     stu->object = (char*)malloc(OBJECT_LEN);
     32     if (!stu->object)
     33     {
     34     goto FAILED;
     35     }
     36     stu->home_address = (char*)malloc(HOME_ADDR_LEN);
     37     if (!stu->home_address)
     38     {
     39     goto FAILED;
     40     }
     41     stu->phone = (char*)malloc(PHONE_LEN);
     42     if (!stu->phone)
     43     {
     44     goto FAILED;
     45     }
     46     return 0;
     47 FAILED:
     48     fprintf(stdout, "malloc error.errno:%u,reason:%s
    ",
     49         errno, strerror(errno));
     50     return -1;
     51 }
     52 
     53 static void free_student_info(Student *stu)
     54 {
     55     if (stu->id)
     56     {
     57     free(stu->id);
     58     stu->id = NULL;
     59     }
     60     if (stu->name)
     61     {
     62     free(stu->name);
     63     stu->name = NULL;
     64     }
     65     if (stu->gender)
     66     {
     67     free(stu->gender);
     68     stu->gender = NULL;
     69     }
     70     if (stu->object)
     71     {
     72     free(stu->object);
     73     stu->object = NULL;
     74     }
     75     if (stu->home_address)
     76     {
     77     free(stu->home_address);
     78     stu->home_address = NULL;
     79     }
     80     if (stu->phone)
     81     {
     82     free(stu->phone);
     83     stu->phone = NULL;
     84     }
     85 }
     86 
     87 static void set_student_info(Student *stu)
     88 {
     89     const char *id = "2013111011";
     90     const char *name = "Anker";
     91     const char *gender = "male";
     92     const char *object = "computer";
     93     const char *address = "shen zheng";
     94     const char *phone = "0102345678";
     95     
     96     strncpy(stu->id, id, ID_LEN);
     97     strncpy(stu->name, name, NAME_LEN);
     98     strncpy(stu->gender, gender, GENDER_LEN);
     99     stu->age = 23;
    100     strncpy(stu->object, object, OBJECT_LEN);
    101     strncpy(stu->home_address, address, HOME_ADDR_LEN);
    102     strncpy(stu->phone, phone, PHONE_LEN);
    103 }
    104 
    105 void print_student_info(Student *stu)
    106 {
    107     printf("id: %s
    ",stu->id);
    108     printf("name: %s
    ",stu->name);
    109     printf("age: %d
    ",stu->age);
    110     printf("gender:%s
    ",stu->gender);
    111     printf("object: %s
    ",stu->object);
    112     printf("home address: %s
    ",stu->home_address);
    113     printf("phone: %s
    ",stu->phone);
    114 }
    115 
    116 int main()
    117 {
    118     Student stu = STUDENT__INIT;
    119     void *buf = NULL;
    120     unsigned int len ;
    121     Student *msg = NULL;
    122 
    123     if (malloc_student_info(&stu) == -1) {
    124         exit(0);
    125     }   
    126     set_student_info(&stu);
    127 
    128     //get student packed size
    129     len = student__get_packed_size(&stu);
    130     printf("size of student info : %u
    ",len);
    131     buf = malloc(len);
    132     //put student info pack to buf
    133     student__pack(&stu, buf);
    134 
    135     //unpack student info from buf
    136     msg = student__unpack(NULL, len, buf);
    137     print_student_info(msg);
    138     //free msg
    139     student__free_unpacked(msg, NULL);
    140 
    141     free(buf);
    142     free_student_info(&stu);
    143 
    144     return 0;
    145 }

    编译命令: gcc student.pb-c.c main.c -o main -lprotobuf-c

    测试结果如下所示:

    3、参考网址

    http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html

    https://code.google.com/p/protobuf-c/wiki/Examples

  • 相关阅读:
    文件上传&ContentType请求格式
    Ajax的简单操作
    外键的变种,单表和多表的查询
    Sql 库和表的基本操作、基本数据类型
    协程、IO多路复用、
    线程/进程锁、池,进程的数据共享
    进程和线程相关
    用wampserver安装thinksns时点击index.php显示空白
    类中的初始化函数作用
    python中的from XX import YY与import YY
  • 原文地址:https://www.cnblogs.com/Anker/p/3416541.html
Copyright © 2011-2022 走看看