1、前言 項目中用到protobuf-c進(jìn)行數(shù)據(jù)序列化,好處在于后期程序擴展性非常好,只需要改動proto的定義就可以保持兼容,非常的靈活方便。關(guān)于protobuf-c的詳細(xì)介紹可以參考google官方文檔。https://code.google.com/p/protobuf-c/。在此簡單的介紹一下基本功能。proto文件格式如下所示: message AMessage { requried int32 a = 1; //a必須出現(xiàn) optional string b = 2; //b是可選的 repeated int32 c = 3; //c是數(shù)組 } 字段規(guī)則類型: required:表示后面的數(shù)據(jù)是必須的。 optional:表示后面數(shù)據(jù)是可選的。 repeated:表示后面的數(shù)據(jù)是一個數(shù)組。 標(biāo)量數(shù)值類型
2、測試程序 編寫一個學(xué)生信息的proto,proto文件內(nèi)容如下所示: 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 }
編譯命令: proto-c --c_cout=. student.proto 生成student.pb-c.c 和 student.pb-c.h兩個文件。student.pb-c.h文件內(nèi)容如下所示: 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 unsigned int len = student__get_packed_size(&stu); 120 printf("size of student info : %u\n",len); 121 if (malloc_student_info(&stu) == -1) 122 { 123 exit(0); 124 } 125 set_student_info(&stu); 126 print_student_info(&stu); 127 free_student_info(&stu); 128 return 0; 129 } 編譯命令: gcc student.pb-c.c main.c -o main -lprotobuf-c 測試結(jié)果如下所示: 3、參考網(wǎng)址 http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html |
|