protobuf-c的学习总结
1、前言
项目中用到protobuf-c进行数据序列化,好处在于后期程序扩展性非常好,只需要改动proto的定义就可以保持兼容,非常的灵活方便。关于protobuf-c的详细介绍可以参考google官方文档。https://code.google.com/p/protobuf-c/。在此简单的介绍一下基本功能。proto文件格式如下所示:
message AMessage
{
requried int32 a = ; //a必须出现
optional string b = ; //b是可选的
repeated int32 c = ; //c是数组
}
字段规则类型:
required:表示后面的数据是必须的。
optional:表示后面数据是可选的。
repeated:表示后面的数据是一个数组。
标量数值类型
|
.proto类型 |
Java 类型 |
C++类型 |
备注 |
|
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 |
可能包含任意顺序的字节数据。 |
2、测试程序
编写一个学生信息的proto,proto文件内容如下所示:
message Student
{
required string id = ;
required string name = ;
required string gender = ;
required int32 age = ;
required string object = ;
required string home_address = ;
required string phone = ;
}
编译命令: protoc-c --c_cout=. 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 <google/protobuf-c/protobuf-c.h> 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, , 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 */
测试proto程序如下所示:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#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 ;
FAILED:
fprintf(stdout, "malloc error.errno:%u,reason:%s\n",
errno, strerror(errno));
return -;
} 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 = "";
const char *name = "Anker";
const char *gender = "male";
const char *object = "computer";
const char *address = "shen zheng";
const char *phone = ""; strncpy(stu->id, id, ID_LEN);
strncpy(stu->name, name, NAME_LEN);
strncpy(stu->gender, gender, GENDER_LEN);
stu->age = ;
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) == -) {
exit();
}
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 ;
}
编译命令: gcc student.pb-c.c main.c -o main -lprotobuf-c
测试结果如下所示:

3、参考网址
http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html
https://code.google.com/p/protobuf-c/wiki/Examples
protobuf-c的学习总结的更多相关文章
- protobuf中会严重影响时间和空间损耗的地方
http://blog.chinaunix.net/uid-26922071-id-3723751.html 当前项目中普遍用到GOOGLE 的一个开源大作PROTOBUF,把它作为网络应用层面的传输 ...
- Protobuf在Python中的应用(序列化数据)
1.了解Protobuf Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单.您可以定义数据的结构化,然后可 ...
- 移动端IM开发者必读(二):史上最全移动弱网络优化方法总结
1.前言 本文接上篇<移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”>,关于移动网络的主要特性,在上篇中已进行过详细地阐述,本文将针对上篇中提到的特性,结合我们的实践经 ...
- go语言学习--protobuf的学习
最近在学习中遇到了protobuf,哇喔竟然不知道,马上进行了学习,protobuf也是数据解析的方式,平时使用最多的是json和xml,那么好了,对比下他们的区别,并且附上protobuf的使用. ...
- 学习 protobuf(一)—— ubuntu 下 protobuf 2.6.1 的安装
下载地址:https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz(如果初次下载失败,不妨多试 ...
- Netty学习(七)-Netty编解码技术以及ProtoBuf和Thrift的介绍
在前几节我们学习过处理粘包和拆包的问题,用到了Netty提供的几个解码器对不同情况的问题进行处理.功能很是强大.我们有没有去想这么强大的功能是如何实现的呢?背后又用到了什么技术?这一节我们就来处理这个 ...
- Netty学习——Netty和Protobuf的整合(二)
Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...
- Netty学习——Netty和Protobuf的整合(一)
Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...
- Netty学习——Google Protobuf使用方式分析和环境搭建
Google Protobuf使用方式分析 在RPC框架中,Google Protobuf是很常用的一个库,和Apache Thrift 是同款的用于进行序列化的第三方库.原理都是大同小异,无非就是使 ...
- google protobuf学习笔记:windows下环境配置
欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/45371743 protobuf的使用和原理,请查看:http:/ ...
随机推荐
- Android开发之解决APP启动白屏或者黑屏闪现的问题
在做搜芽的过程中,发现那个外包人缘做的不行,由于启动的时候会停顿,然后白屏一会,联想到几个月前我在我的三僚企业通信软件里面拉起9K-Mail的时候也会黑屏,所以决定学习一下.解决一下.这不,万能的网络 ...
- oracle like 条件拼接
(1) ibatis xml配置:下面的写法只是简单的转义 namelike '%$name$%' (2) 这时会导致sql注入问题,比如参数name传进一个单引号“'”,生成的sql语句会是:nam ...
- 【Go命令教程】2. go build
go build 命令用于编译我们 指定的 源码文件 或 代码包 以及它们的依赖包. 例如,如果我们在执行 go build 命令时不后跟任何代码包,那么命令将试图编译当前目录所对应的代码包.例如, ...
- spanner-becoming-a-sql-system 2017
https://blog.acolyer.org/2017/07/03/spanner-becoming-a-sql-system/?utm_source=tuicool&utm_medium ...
- chrome浏览器调试报错:Failed to load resource: the server responsed width a status of 404 (Not Found)…http://127.0.0.1:5099/favicon.ico
chrome浏览器在调试的时候默认会查找根目录下的favicon.ico文件,如果不存在就会报错. 解决办法:F12,点击<top frame>左侧漏斗形状的filter,勾选上" ...
- C#中一种替换switch语句更优雅的写法
今天在项目中遇到了使用switch语句判断条件,但问题是条件比较多,大概有几十个条件,满屏幕的case判断,是否有更优雅的写法替代switch语句呢? 假设有这样的一个场景:商场经常会根据情况采取不同 ...
- 发布网站时应该把debug设置false
在ASP.NET项目根目录下的Web.config中有这样的一个节点: <compilation debug="true" targetFramework="4.5 ...
- Java异常(三) 《Java Puzzles》中关于异常的几个谜题
概要 本章介绍<Java Puzzles>中关于异常的几个谜题.这一章都是以代码为例,相比上一章看起来更有意思.内容包括:谜题1: 优柔寡断谜题2: 极端不可思议谜题3: 不受欢迎的宾客谜 ...
- WordPress主题开发实例:根据不同分类使用不同模板
分类实现效果: 点击"产品"相关分类,显示 否则显示 创建文件: category.php cat-news.php cat-product.php 由于点击分类时wordpres ...
- linux文件名称查找which,whereis,locate
1. 文件名称查找 使用find查询时.因为磁盘查询.所以速度较慢. 所以linux下查询更常使用which, whereis, locate来查询,因为是利用数据库查询.所以速度非常快. 2. wh ...