protobuf-c的学习总结

来源:互联网 发布:二维数组赋值运算 编辑:程序博客网 时间:2024/06/16 09:04

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]uint64Uses 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  _Student20 {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__init37                      (Student         *message);38 size_t student__get_packed_size39                      (const Student   *message);40 size_t student__pack41                      (const Student   *message,42                       uint8_t             *out);43 size_t student__pack_to_buffer44                      (const Student   *message,45                       ProtobufCBuffer     *buffer);46 Student *47        student__unpack48                      (ProtobufCAllocator  *allocator,49                       size_t               len,50                       const uint8_t       *data);51 void   student__free_unpacked52                      (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_DECLS68 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\n", 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\n",stu->id);108     printf("name: %s\n",stu->name);109     printf("age: %d\n",stu->age);110     printf("gender:%s\n",stu->gender);111     printf("object: %s\n",stu->object);112     printf("home address: %s\n",stu->home_address);113     printf("phone: %s\n",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 size129     len = student__get_packed_size(&stu);130     printf("size of student info : %u\n",len);131     buf = malloc(len);132     //put student info pack to buf133     student__pack(&stu, buf);134 135     //unpack student info from buf136     msg = student__unpack(NULL, len, buf);137     print_student_info(msg);138     //free msg139     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

0 0
原创粉丝点击