Protoc安装
1、下载Protocol Buffers的安装包: https://github.com/google/protobuf 和https://github.com/protobuf-c/protobuf-c
2、安装步骤:
安装需要的依赖包:
[root@hanbo]# apt-get install autoconf automake libtool curl make g++ unzip
[root@hanbo]# unzip protobuf-master.zip
[root@hanbo]# cd protobuf-master
生成configure文件的脚本文件,如果不执行这步,以下操作将通不过
[root@hanbo protobuf-master]# ./autogen.sh
[root@hanbo protobuf-master]# ./configure
可以修改安装目录通过 ./configure --prefix=命令,统一安装在/usr/local/protobuf下 (一般不要修改,配置不完整会影响使用)
[root@hanbo protobuf-master]# ./configure --prefix=/usr/local/protobuf
[root@hanbo protobuf-master]# make
[root@hanbo protobuf-master]# make check
[root@hanbo protobuf-master]# make install
[root@hanbo protobuf-master]# ldconfig # refresh shared library cache.
一、简介
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。
它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种
语言的 API。
二、proto文件格式
message AMessage
{
requried int32 a = 1; //a必须出现
optional string b = 2; //b是可选的
repeated int32 c = 3; //c是数组
}
字段规则类型:
required:表示后面的数据是必须的。
optional:表示后面数据是可选的。
repeated:表示后面的数据是一个数组。
三、测试程序
编写一个学生信息的proto,proto文件内容如下所示:
message Student
{
required string id = 1;
required string name = 2;
required string gender = 3;
required int32 age = 4;
required string object = 5;
required string home_address = 6;
required string phone = 7;
}
编译命令: protoc-c --c_out=. student.proto
生成student.pb-c.c 和 student.pb-c.h两个文件。student.pb-c.h文件内容如下所示:
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
#ifndef PROTOBUF_C_student_2eproto__INCLUDED
#define PROTOBUF_C_student_2eproto__INCLUDED
#include
PROTOBUF_C_BEGIN_DECLS
typedef struct _Student Student;
/* --- enums --- */
/* --- messages --- */
struct _Student
{
ProtobufCMessage base;
char *id;
char *name;
char *gender;
int32_t age;
char *object;
char *home_address;
char *phone;
};
#define STUDENT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&student__descriptor) \
, NULL, NULL, NULL, 0, NULL, NULL, NULL }
/* Student methods */
void student__init
(Student *message);
size_t student__get_packed_size
(const Student *message);
size_t student__pack
(const Student *message,
uint8_t *out);
size_t student__pack_to_buffer
(const Student *message,
ProtobufCBuffer *buffer);
Student *
student__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void student__free_unpacked
(Student *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*Student_Closure)
(const Student *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCMessageDescriptor student__descriptor;
PROTOBUF_C_END_DECLS
#endif /* PROTOBUF_student_2eproto__INCLUDED */
#include
#include
#include
#include
#include "student.pb-c.h"
#define ID_LEN 11
#define NAME_LEN 32
#define GENDER_LEN 10
#define OBJECT_LEN 20
#define HOME_ADDR_LEN 96
#define PHONE_LEN 12
static int malloc_student_info(Student *stu)
{
stu->id = (char*)malloc(ID_LEN);
if (!stu->id)
{
goto FAILED;
}
stu->name = (char*)malloc(NAME_LEN);
if (!stu->name)
{
goto FAILED;
}
stu->gender = (char*)malloc(GENDER_LEN);
if (!stu->gender)
{
goto FAILED;
}
stu->object = (char*)malloc(OBJECT_LEN);
if (!stu->object)
{
goto FAILED;
}
stu->home_address = (char*)malloc(HOME_ADDR_LEN);
if (!stu->home_address)
{
goto FAILED;
}
stu->phone = (char*)malloc(PHONE_LEN);
if (!stu->phone)
{
goto FAILED;
}
return 0;
FAILED:
fprintf(stdout, "malloc error.errno:%u,reason:%s\n",
errno, strerror(errno));
return -1;
}
static void free_student_info(Student *stu)
{
if (stu->id)
{
free(stu->id);
stu->id = NULL;
}
if (stu->name)
{
free(stu->name);
stu->name = NULL;
}
if (stu->gender)
{
free(stu->gender);
stu->gender = NULL;
}
if (stu->object)
{
free(stu->object);
stu->object = NULL;
}
if (stu->home_address)
{
free(stu->home_address);
stu->home_address = NULL;
}
if (stu->phone)
{
free(stu->phone);
stu->phone = NULL;
}
}
static void set_student_info(Student *stu)
{
const char *id = "2016041117";
const char *name = "Hslong";
const char *gender = "male";
const char *object = "computer";
const char *address = "han dan";
const char *phone = "03111234567";
strncpy(stu->id, id, ID_LEN);
strncpy(stu->name, name, NAME_LEN);
strncpy(stu->gender, gender, GENDER_LEN);
stu->age = 25;
strncpy(stu->object, object, OBJECT_LEN);
strncpy(stu->home_address, address, HOME_ADDR_LEN);
strncpy(stu->phone, phone, PHONE_LEN);
}
void print_student_info(Student *stu)
{
printf("id: %s\n",stu->id);
printf("name: %s\n",stu->name);
printf("age: %d\n",stu->age);
printf("gender:%s\n",stu->gender);
printf("object: %s\n",stu->object);
printf("home address: %s\n",stu->home_address);
printf("phone: %s\n",stu->phone);
}
int main()
{
Student stu = STUDENT__INIT;
void *buf = NULL;
unsigned int len ;
Student *msg = NULL;
if (malloc_student_info(&stu) == -1) {
exit(0);
}
set_student_info(&stu);
//get student packed size
len = student__get_packed_size(&stu);
printf("size of student info : %u\n",len);
buf = malloc(len);
//put student info pack to buf
student__pack(&stu, buf);
//unpack student info from buf
msg = student__unpack(NULL, len, buf);
print_student_info(msg);
//free msg
student__free_unpacked(msg, NULL);
free(buf);
free_student_info(&stu);
return 0;
}
编译命令: gcc student.pb-c.c main.c -o main -lprotobuf-c
测试结果如下所示: