2019独角兽企业重金招聘Python工程师标准>>>

Simple complete example

A simple file, amessage.proto file following the language guide:

 message AMessage{required int32 a=1; optional int32 b=2;}

Generate .h and .c files from the command-line in your current working directory:

 protoc-c --c_out=. amessage.proto

Serialize/pack the AMessage as follows:

#include <stdio.h>
#include <stdlib.h>
#include "amessage.pb-c.h"int main (int argc, const char * argv[])
{AMessage msg = AMESSAGE__INIT; // AMessagevoid *buf;                     // Buffer to store serialized dataunsigned len;                  // Length of serialized dataif (argc != 2 && argc != 3){   // Allow one or two integersfprintf(stderr,"usage: amessage a [b]\n");return 1;}msg.a = atoi(argv[1]);if (argc == 3) { msg.has_b = 1; msg.b = atoi(argv[2]); }len = amessage__get_packed_size(&msg);buf = malloc(len);amessage__pack(&msg,buf);fprintf(stderr,"Writing %d serialized bytes\n",len); // See the length of messagefwrite(buf,len,1,stdout); // Write to stdout to allow direct command line pipingfree(buf); // Free the allocated serialized bufferreturn 0;
}

I left most error handling out for brevity. Notice:

the use of

  1. the A_MESSAGE__INIT macro to construct the message

  2. the has_b member corresponds to the optional b field -- required fields do not   have a has_ member.

  3. amessage__get_packed_size returns the length   of the packed data.

  4. a_message__pack serializes the      message.

On the other hand, to deserialize/unpack a message, try code like this:

#include <stdio.h>
#include <stdlib.h>
#include "amessage.pb-c.h"
#define MAX_MSG_SIZE 1024static size_t
read_buffer (unsigned max_length, uint8_t *out)
{size_t cur_len = 0;uint8_t c;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 (int argc, const char * argv[])
{AMessage *msg;// Read packed message from standard-input.uint8_t buf[MAX_MSG_SIZE];size_t msg_len = read_buffer (MAX_MSG_SIZE, buf);// Unpack the message using protobuf-c.msg = amessage__unpack(NULL, msg_len, buf);   if (msg == NULL){fprintf(stderr, "error unpacking incoming message\n");exit(1);}// display the message's fields.printf("Received: a=%d",msg->a);  // required fieldif (msg->has_b)                   // handle optional fieldprintf("  b=%d",msg->b);printf("\n");// Free the unpacked messageamessage__free_unpacked(msg, NULL);return 0;
}

During linking each above program, make sure to include '-lprotobuf-c'

Test by piping one program into the next at command line:

./amessage_serialize 10 2 | ./amessage_deserialize
Writing: 4 serialized bytes
Received: a=10 b=2

Repeated Fields

Here is a simple file, cmessage.proto file:

message CMessage
{repeated int32 c=1;
}

Serialize/pack the CMessage as follows:

#include <stdio.h>
#include <stdlib.h>
#include "cmessage.pb-c.h"int main (int argc, const char * argv[])
{CMessage msg = CMESSAGE__INIT;  // CMessage (repeated int32)void *buf;                      // Buffer to store serialized dataunsigned len,i;                 // Length of serialized datamsg.n_c = argc - 1;                      // Save number of repeated int32msg.c = malloc (sizeof (int) * msg.n_c); // Allocate memory to store int32for (i = 0; i < msg.n_c; i++)msg.c[i] = atoi (argv[i+1]);         // Access msg.c[] as array len = cmessage__get_packed_size (&msg);  // This is calculated packing lengthbuf = malloc (len);                      // Allocate required serialized buffer length cmessage__pack (&msg, buf);              // Pack the datafprintf(stderr,"Writing %d serialized bytes\n",len); // See the length of messagefwrite (buf, len, 1, stdout);            // Write to stdout to allow direct command line pipingfree (msg.c); // Free storage for repeated int32             free (buf);   // Free serialized bufferreturn 0;
}

I left most error handling out for brevity. Notice:

  1. the use of      the C_MESSAGE__INIT macro to construct the message

  2. the n_XXX      member is generated for a repeated field XXX.

On the other hand, if you want to deserialize/unpack a message, try code like this:

#include <stdio.h>
#include "cmessage.pb-c.h"
#define MAX_MSG_SIZE  4096int main (int argc, const char * argv[])
{CMessage *msg;uint8_t buf[MAX_MSG_SIZE];size_t msg_len = read_buffer (MAX_MSG_SIZE, buf);msg = cmessage__unpack (NULL, len, buf); // Deserialize the serialized inputif (msg == NULL){ // Something failedfprintf(stderr, "error unpacking incoming message\n");return 1;}for (i = 0; i < msg->n_c; i++){ // Iterate through all repeated int32if (i > 0)printf (", ");printf ("%d", msg->c[i]);}printf ("\n");cmessage__free_unpacked(msg,NULL); // Free the message from unpack()return 0;
}

Test by piping one program into the next at command line:

./cmessage_serialize 12 3 4 | ./cmessage_deserialize
Writing: 6 serialized bytes
12, 3, 4

Constructing Submessages

Here is a simple file, dmessage.proto file:

message Submessage
{required int32 value=1;
}message DMessage
{required Submessage a=1;optional Submessage b=2;
}

Here DMessage consists of one or two integers (a is one int and required; b is one int and optional).

#include <stdio.h>
#include <stdlib.h>
#include "dmessage.pb-c.h"int main (int argc, const char * argv[])
{DMessage msg    = DMESSAGE__INIT;   // DMESSAGESubmessage sub1 = SUBMESSAGE__INIT; // SUBMESSAGE ASubmessage sub2 = SUBMESSAGE__INIT; // SUBMESSAGE Bvoid *buf;unsigned len;if (argc != 2 && argc != 3){   // Allow one or two integersfprintf(stderr,"usage: dmessage a [b]\n");return 1;}sub1.value = atoi (argv[1]); msg.a = &sub1;               // Point msg.a to sub1 data// NOTE: has_b is not required like amessage, therefore check for NULL on deserialzeif (argc == 3) { sub2.value = atoi (argv[2]); msg.b = &sub2; } // Point msg.b to sub2 datalen = dmessage__get_packed_size (&msg); // This is the calculated packing lengthbuf = malloc (len);                     // Allocate memorydmessage__pack (&msg, buf);             // Pack msg, including submessagesfprintf(stderr,"Writing %d serialized bytes\n",len); // See the length of messagefwrite (buf, len, 1, stdout);           // Write to stdout to allow direct command line pipingfree(buf); // Free the allocated serialized bufferreturn 0;
}

Notice:

  1. there is no has_ flag for optional      submessages -- if the pointer is non-NULL, then we assume that it is a      value.

On the other hand, if you want to deserialize/unpack a message, try code like this:

#include <stdio.h>
#include "dmessage.pb-c.h"
#define MAX_MSG_SIZE 4096int main (int argc, const char * argv[])
{DMessage *msg;         // DMessage using submessagesSubmessage *sub1,*sub2;// Submessageschar c; int i=0;       // Data holdersuint8_t buf[MAX_MSG_SIZE]; // Input data container for byteswhile (fread(&c,1,1,stdin) != 0){if (i >= MAX_MSG_SIZE){fprintf(stderr,"message too long for allocated buffer\n");return 1;}buf[i++] = c;}msg = dmessage__unpack(NULL,i,buf); // Deserialize the serialized inputif (msg == NULL){ // Something failedfprintf(stderr,"error unpacking incoming message\n");return 1;}sub1 = msg->a; sub2 = msg->b;printf("Received: a=%d",sub1->value);if (msg->b != NULL) printf(" b=%d",sub2->value);printf("\n");dmessage__free_unpacked(msg,NULL);return 0;
}

Test by piping one program into the next at command line:

./dmessage_serialize 4 5 | ./dmessage_deserialize
Writing: 8 serialized bytes
Received: a=4 b=5
./dmessage_serialize 4 | ./dmessage_deserialize
Writing: 4 serialized bytes
Received: a=4

Constructing Repeated Submessages

Here is a simple file, emessage.proto file:

message Submessage
{required int32 value=1;
}message EMessage
{repeated Submessage a=1;
}

Here DMessage consists of one or two integers (a is one int and required; b is one int and optional).

#include <stdio.h>
#include <stdlib.h>
#include "dmessage.pb-c.h"int main (int argc, const char * argv[])
{Submessage **subs;void *buf;unsigned len;subs = malloc (sizeof (Submessage*) * (argc-1));for (i = 1; i < argc; i++){subs[i-1] = malloc (sizeof (Submessage));submessage__init (subs[i-1]);subs[i-1]->value = atoi(argv[i]);}    msg.n_a = argc-1;msg.a = subs;len = emessage__get_packed_size (&msg); // This is the calculated packing lengthbuf = malloc (len);                     // Allocate memoryemessage__pack (&msg, buf);             // Pack msg, including submessagesfprintf(stderr,"Writing %d serialized bytes\n",len); // See the length of messagefwrite (buf, len, 1, stdout);           // Write to stdout to allow direct command line pipingfree(buf); // Free the allocated serialized bufferfor (i = 1; i < argc; i++)free (subs[i]);free (subs); return 0;
}

Notice that repeated fields create two fields, in this case n_a, the number of submessages, and a the submessages themselves. Also note that ais an array of pointers to messages.

On the other hand, if you want to deserialize/unpack a message, try code like this:

#include <stdio.h>
#include "emessage.pb-c.h"
#define MAX_MSG_SIZE 4096int main (int argc, const char * argv[])
{EMessage *msg;char c; int i=0;uint8_t buf[MAX_MSG_SIZE]; // Input data container for byteswhile (fread(&c,1,1,stdin) != 0){if (i >= MAX_MSG_SIZE){fprintf(stderr,"message too long for allocated buffer\n");return 1;}buf[i++] = c;}msg = emessage__unpack(NULL,i,buf); // Deserialize the serialized inputif (msg == NULL){fprintf(stderr,"error unpacking incoming message\n");return 1;}for (i = 0; i < msg->n_a; i++)printf ("%d\n", msg->a[i]->value);emessage__free_unpacked(msg,NULL);return 0;
}

Test by piping one program into the next at command line:

./emessage_serialize 4 5 | ./emessage_deserialize
Writing: 8 serialized bytes
4
5
./emessage_serialize 4 5 8| ./emessage_deserialize
4
5
8

转载于:https://my.oschina.net/u/572632/blog/266452

protobuf-c使用说明相关推荐

  1. protobuf序列化使用说明

    2019独角兽企业重金招聘Python工程师标准>>> protobuf转换方法 编写protobuf代码如下: package netty; option java_package ...

  2. protobuf使用说明

    1..proto文件为要生成.java文件的模板文件,其中包含名称空间.文件名等信息 2.cmd中进入当前目录D:\JAVA\protoc-2.5.0-win32 3.运行 protoc.exe -- ...

  3. Google Protobuf 开发指南

    为什么80%的码农都做不了架构师?>>>    Google Protobuf开发指南 1.简介 l  它是开源项目:http://code.google.com/p/protobu ...

  4. grpc+gateway使用说明

    文章目录 grpc+gateway 使用说明(MAC版) 1. 安装 1.1 安装golang 1.2 安装protoc 1.3 安装grpc相关脚本 2. 编写protoc文件 2.1 添加prot ...

  5. Skynet 服务器开发 (四) 使用pbc(protobuf)

    转载自:https://blog.csdn.net/u010693827/article/details/85689483 引言: 假如我们要建立的skynet服务器与客户端的连接方式为长连接,且选择 ...

  6. ncnn环境搭建一 - windows下protobuf编译安装

    1. 环境 安装环境采用visual studio 2015 + protobuf 3.4.0 + ncnn 2. visual studio 2015安装 visual studio采用的是 vs2 ...

  7. abaqus高性能服务器怎么用,高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF...

    高性能计算平台ABAQUS任务调度使用说明作者陈林E-Mailchenlin.PDF 高性能计算平台ABAQUS 任务调度使用说明 作者:陈林 E-Mail:chenlin@ 日期:2017-1-10 ...

  8. linux 文件拷贝并替换,Linux_cmd replace 文件替换使用说明,帮助信息: 复制代码 代码如 - phpStudy...

    cmd replace 文件替换使用说明 帮助信息: 复制代码 代码如下: 替换文件. REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [ ...

  9. 使用Protobuf文件一键生成Java类

    使用Protobuf文件生成Java类 .proto 文件生成 .java 参考 看了一篇文章:主题是 proto 先生成 desc,然后在用 FreeMarker 模板引擎来做代码自动生成了: .p ...

  10. 简单protobuf

    protobuf的数据类型,有最简单的那种数据类型,就是一个文件中,定义了一个message 可以在一个文件中定义两个message,两个message之间是没有关联的 可以在一个文件中,定义两个me ...

最新文章

  1. BZOJ 2535:NOI 2010 航空管制
  2. spyder ipython控制台_Spyder Ipython控制台完全忽略打印语句
  3. Mockito:一个强大的用于Java开发的模拟测试框架
  4. mysql5.6开启binlog日志
  5. 【poj3375】 Network Connection
  6. Caffe神经网络结构汇总
  7. win 安装 Xshell 5
  8. 酷派大观4 8970 刷android 4.4,酷派5890驱动 酷派 8970L(大观4)recovery卡刷通用刷机教程...
  9. android6.0 power按键深入分析
  10. Vue和Element第一天
  11. Android AR ---HelloAR(用的EasyAR 免费版)
  12. sql中将字符串转换为decimal
  13. 萝卜开会直播NO.2 | 换一个十年,感受不一样的世界
  14. 在EXCEL中如何设置打印区域,只打印部分区域
  15. vue项目中动态显示时间
  16. 剪贴板查看器:CopyClip 2 for Mac
  17. php5.3 register_globals,在PHP 5.3中PHP寄存器全局支持?(PHP register globals support in PHP 5.3?)...
  18. 物理学的困惑: 科学的道德规范和伦理观
  19. 人生是什么?感悟3:工作不是生活的全部
  20. 物联网设备分为哪几种,NB-IoT主要有什么优势?

热门文章

  1. 前阿里 P9 级员工称离婚是模拟测试,已回滚复婚!
  2. O(n^2) 级别的排序算法
  3. 英特尔变身数据公司 未来最大数据市场定是中国
  4. 局域网交换(交换机三大原理.基本配置)
  5. 批量修改table和index 的表空间
  6. 防用户误删除,耗费一周时间把DeleteMark标志都加上来了,所有的删除操作从“物理删除”转为“逻辑删除”...
  7. alibaba面试题
  8. NSNotification消息通知实现源码(观察者模式原理)
  9. jsp中的contentType与pageEncoding的区别和作用
  10. 对DIP IoC DI的理解与运用