protobuf-c的學習總結

一、前言html

         項目中用到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:表示後面的數據是必須的。ui

optional:表示後面數據是可選的。google

repeated:表示後面的數據是一個數組。編碼

標量數值類型spa

.proto類型code

Java 類型htm

C++類型blog

備註

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

可能包含任意順序的字節數據。

二、測試程序

  編寫一個學生信息的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\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 size
129     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 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

測試結果以下所示:

三、參考網址

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

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

相關文章
相關標籤/搜索