您的位置:首页 > 其它

protobuf-c学习小结

2015-04-10 12:20 253 查看
由于项目的需要,利用了一下午进行了protobuf-c的学习,下面来总结一下。

简介:

protocolbuffer(以下简称PB)是google
的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:javac++python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

项目中用到protobuf-c进行数据序列化,好处在于后期程序扩展性非常好,只需要改动proto的定义就可以保持兼容,非常的灵活方便。

安装:

由于我实在ubuntu下进行使用,所以安装很方便,执行如下两步就可以了:

<pre name="code" class="plain">1. 首先安装protobuf。
sudo apt-get install protobuf-compiler libprotobuf-dev libprotoc-dev

2. 再而安装protobuf-c
sudo apt-get install libprotobuf-c0-dev protobuf-c-compiler



编写:

文件格式:

message AMessage
{
     requried  int32  a = 1;  //a必须出现
     optional  string b = 2;  //b是可选的
     repeated  int32  c = 3;  //c是数组
}
字段规则类型:

required:表示后面的数据是必须的。

optional:表示后面数据是可选的。

repeated:表示后面的数据是一个数组。


下面就正式编写一个.proto文件:student.proto

message student
{
	required string id=1;
	required string name=2;
	required int32 age=3;
}
编译:



分析:protoc-c就是编译命令,--c_out=. 表示在当前目录下生成.h和.c两个文件,最后面的就是源文件。

测试:

student.proto:

message Student
{
	required string id=1;
	required string name=2;
	required int32 age=3;
}

enum Grade
{
	PRIMARY=0;
	JUNIOR=1;
	SENIOR=2;
	COLLEGE=3;
}

message School
{
	optional Grade grade=1[default=SENIOR];
	required Student student=2;
}


student_p.c:

/*************************************************************************
  > File Name: student_p.c
  > Author: AnSwEr
  > Created Time: 2015年04月10日 星期五 14时04分48秒
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "student.pb-c.h"
#include <string.h>

#define ID_LEN 11
#define NAME_LEN 11

int main()
{
	void *buf=NULL;
	unsigned  len;

	/*init*/
	Student stu ;
	student__init(&stu);
	School scl;
	school__init(&scl); 

	/*set student's value*/
	stu.id = malloc(ID_LEN);
	stu.name = malloc(NAME_LEN);
	strcpy(stu.name,"answer");
	strcpy(stu.id,"092312125");
	stu.age=22;
	
	/*set grade value*/
	Grade gra = GRADE__PRIMARY;
	
	/*set school value*/
	if(gra >= 0)
	{ 
		scl.has_grade = 1;
		scl.grade = gra;
	}
	scl.student = &stu;

	/*packing*/
	len = school__get_packed_size(&scl);
	buf = malloc(len);
	school__pack(&scl,buf);
	fprintf(stderr, "write %d serialized bytes\n",len);
	fwrite(buf,len,1,stdout);

	/*freeing*/
	free(buf);
	free(stu.id);
	free(stu.name);
	return 0;
}


student_up.c:

/*************************************************************************
  > File Name: student_up.c
  > Author: AnSwEr
  > Created Time: 2015年04月10日 星期五 14时13分52秒
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "student.pb-c.h"
#include <string.h>

#define MAX_MSG_LEN 1024

static size_t read_buff(unsigned max_length,uint8_t *out)
{
	size_t cur_len=0,nread=0;
	while((nread = fread(out+cur_len, 1, max_length - cur_len, stdin)) != 0)
	{
		cur_len += nread;
		if(cur_len == max_length)
		{
			fprintf(stderr,"max message length exceeded\n");
			exit(1);
		}
	}
	return cur_len;
}

int main()
{
	/*initing*/
	School *scl;
	school__init(scl);

	uint8_t buf[MAX_MSG_LEN];
	/*unpacking*/
	size_t  msg_len = read_buff(MAX_MSG_LEN,buf);
	scl = school__unpack(NULL,msg_len,buf);
	if(scl == NULL)
	{
		fprintf(stderr,"error unpacking incoming message\n");
		exit(1);
	}
	/*result*/
	if(scl->has_grade)
	{   
		switch(scl->grade)
		{
			case 0:
				printf("grade:primary\n");
				break;
			case 1:
				printf("grade:junior\n");
				break;
			case 2:
				printf("grade:senior\n");
				break;
			case 3:
				printf("grade:college\n");
				break;
			default:
				printf("grade unknow\n");
		}
	}
	printf("id:%s\n",scl->student->id);
	printf("name:%s\n",scl->student->name);
	printf("age:%d\n", scl->student->age);
	return 0;
}


编译运行:



注意编译时需要链接protobuf-c。

好啦,现在可以简单的使用了。对于运用于项目开发而言,已经足够了,就不再深入探讨了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: