protobuf编译和使用(C语言)
本文主要讲述linux下C语言使用protobuf相关说明
XML和JSON是目前常用的数据交换格式,它们直接使用字段名称维护序列化后类实例中字段与数据之间的映射关系,一般用字符串的形式保存在序列化后的字节流中。消息和消息的定义相对独立,可读性较好。但序列化后的数据字节很大,序列化和反序列化的时间较长,数据传输效率不高。
Protobuf是Google提供一个具有高效的协议数据交换格式工具库,类似于JSON,Protobuf和XML、JSON序列化的方式不同,采用了二进制字节的序列化方式,用字段索引和字段类型通过算法计算得到字段之前的关系映射,从而达到更高的时间效率和空间效率,特别适合对数据大小和传输速率比较敏感的场合使用。
syntax = "proto2"; // proto3 必须加此注解
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;
}
./autogen.sh
./configure --prefix=/XX/bin/protobuflib/
make
make install
./autogen.sh
./configure --host=arm-linux CC=XX CXX=XX --prefix=/XX/bin/protobuflib/
make
make install
由于我的开发环境是linux C语言环境,protobuf仅支持C++,所以这里引入一个其他开源库protobuf-c,解决C语言的支持问题,编译protobuf-c前,需要编译及安装好protobuf。
PKG_CONFIG_PATH=/XX/bin/protobuflib/
export PKG_CONFIG_PATH
./autogen.sh
./configure --prefix=/XX/bin/protobufc/
make
make install
./autogen.sh
./configure --host=arm-linux CC=XX CXX=XX --prefix=/XX/bin/protobufc/
make
make install
编写一个学生信息的proto,proto文件内容如下所示:
syntax = "proto2"; // proto3 必须加此注解
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;
}
使用如下命令生成student.pb-c.c 和 student.pb-c.h文件。
protoc-c --c_cout=. student.proto
编写测试程序:
#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 = "2013111011";
const char *name = "Anker";
const char *gender = "male";
const char *object = "computer";
const char *address = "shen zheng";
const char *phone = "0102345678";
strncpy(stu->id, id, ID_LEN);
strncpy(stu->name, name, NAME_LEN);
strncpy(stu->gender, gender, GENDER_LEN);
stu->age = 23;
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
部分内容摘自以下网址:
http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html
https://code.google.com/p/protobuf-c/wiki/Examples
https://www.cnblogs.com/Anker/p/3416541.html