protobuf-c简介与使用

protobuf-c简介

一、数据类型照

proto类型C/C++类型proto类型C/C++类型
doubledoublefloatfloat
int32int32int64int64
uint32uint32uint64uint64
sint32int32sint64int64
fixed32uint32fixed64uint64
sfixed32int32sfixed64int64
boolboolstringstring(c++),char*( c )

二、proto文件格式与类型

proto syntax="proto2"; #指定proto版本,推荐用2

message ID #消息名称:结构体名称
{
    required string id = 1;
}
# 消息结构可嵌套,也可包含其他proto文件,使用其中的消息结构
message talk
{   
    required ID s_id = 1; #required:该域必须有且仅有一个实例
    repeated ID d_id = 2; #repeated:该域可有0至多个实例
    required string content = 3;
    optional int64 timeout = 4; #optional:该域可有0或1个实例
}

三、生成头文件与源文件指令

protoc-c --c_out=头文件与源文件输出目录 -I proto文件所在目录 proto文件名

四、对应结构

typedef struct _ID ID;
typedef struct _Talk Talk;

struct  _ID
{
  ProtobufCMessage base;
  char *id;
};

struct  _Talk
{
  ProtobufCMessage base;
  ID *s_id;
  size_t n_d_id;	//对应的repeated域字段名会有一个计数域,填充完实例后需要手动赋值个数,否则序列化域反序列化异常
  ID **d_id;
  char *content;
  protobuf_c_boolean has_timeout;
  int64_t timeout;
};

五、常用宏与接口

//必须初始化实例,否则序列化异常
//为定义的实例初始化:Talk t = TALK__INIT;
TALK__INIT
//初始化动态分配的实例:Talk t = malloc(sizeof(Talk)); talk_init(t);
void   talk__init(Talk *message);
//获取序列化后数据大小,用于为其分配保存序列化后数据的空间
size_t talk__get_packed_size(const Talk   *message);
//将结构序列化进缓存空间
size_t talk__pack(const Talk   *message,uint8_t *out);
//反序列化
Talk * talk__unpack(ProtobufCAllocator  *allocator,size_t len,const uint8_t  *data);
//释放反序列化实例占用空间
void  talk__free_unpacked(Talk *message,ProtobufCAllocator *allocator);
Talk t = TALK__INIT;
size_t len = talk_get_packed_size(&t);
//填充结构数据域
//...
//...
char *buf = (char*)malloc(len);
talk__pack(&t, (uint8_t*)buf);

Talk *tt = talk__unpack(NULL, len, (uint8_t *)buf);
//处理业务
//...
//...
talk__free_unpacked(tt, NULL);

六、demo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "msg.pb-c.h"

int main(int argc, char **argv)
{
    char *buf = NULL;
    Talk t = TALK__INIT;
	Talk *talk = NULL;
    int num = 2;
    size_t len = 0;
    ID* s_id = (ID*)malloc(sizeof(ID));
    ID** d_id = (ID**)malloc(sizeof(ID*) * num);

    t.content = (char*)malloc(100);
    memset(t.content, 0x00, 100);
    strcpy(t.content, "Hello, Protobuf-c.");
    
    id__init(s_id);
    s_id->id = (char*)malloc(7);
    memset(s_id->id, 0x00, 7);
    strcpy(s_id->id, "1234584");
    t.s_id = s_id;
    
    d_id[0] = (ID*)malloc(sizeof(ID));
    d_id[1] = (ID*)malloc(sizeof(ID));
    id__init(d_id[0]);
    id__init(d_id[1]);
    d_id[0]->id = (char*)malloc(7);
    d_id[1]->id = (char*)malloc(7);
    
    memset(d_id[0]->id, 0x00, 7);
    memset(d_id[1]->id, 0x00, 7);
    strcpy(d_id[0]->id, "1234585");
    strcpy(d_id[1]->id, "1234586");
    
    t.d_id = d_id;
    t.n_d_id = num;
    
    len = talk__get_packed_size(&t);
    buf = (char*)malloc(len);
    talk__pack(&t, (uint8_t*)buf);
	
	num = 0;
    talk = talk__unpack(NULL, len, (uint8_t*)buf);
    printf("s_id: %s\n", talk->s_id->id);
    printf("d_id: \t");
    for(num = 0; num < talk->n_d_id; ++num)
    {
        printf("%s\t", talk->d_id[num]->id);
    }
    printf("\nContent: %s\n", talk->content);

    talk__free_unpacked(talk, NULL);
	free(buf);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值