protobuf-c 基本使用及样例

protobuf-c 基本使用及样例

Protobuf简介

https://cloud.tencent.com/developer/article/1199069

一、数据类型照

proto类型 C/C++类型 proto类型 C/C++类型
double double float float
int32 int32 int64 int64
uint32 uint32 uint64 uint64
sint32 int32 sint64 int64
fixed32 uint32 fixed64 uint64
sfixed32 int32 sfixed64 int64
bool bool string string(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文件名

头文件

/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: 2.proto */

/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C__NO_DEPRECATED
#define PROTOBUF_C__NO_DEPRECATED
#endif

#include "2.pb-c.h"
void   id__init
                     (ID         *message)
{
  static const ID init_value = ID__INIT;
  *message = init_value;
}
size_t id__get_packed_size
                     (const ID *message)
{
  assert(message->base.descriptor == &id__descriptor);
  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t id__pack
                     (const ID *message,
                      uint8_t       *out)
{
  assert(message->base.descriptor == &id__descriptor);
  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t id__pack_to_buffer
                     (const ID *message,
                      ProtobufCBuffer *buffer)
{
  assert(message->base.descriptor == &id__descriptor);
  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
ID *
       id__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data)
{
  return (ID *)
     protobuf_c_message_unpack (&id__descriptor,
                                allocator, len, data);
}
void   id__free_unpacked
                     (ID *message,
                      ProtobufCAllocator *allocator)
{
  if(!message)
    return;
  assert(message->base.descriptor == &id__descriptor);
  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
void   talk__init
                     (Talk         *message)
{
  static const Talk init_value = TALK__INIT;
  *message = init_value;
}
size_t talk__get_packed_size
                     (const Talk *message)
{
  assert(message->base.descriptor == &talk__descriptor);
  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t talk__pack
                     (const Talk *message,
                      uint8_t       *out)
{
  assert(message->base.descriptor == &talk__descriptor);
  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t talk__pack_to_buffer
                     (const Talk *message,
                      ProtobufCBuffer *buffer)
{
  assert(message->base.descriptor == &talk__descriptor);
  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Talk *
       talk__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data)
{
  return (Talk *)
     protobuf_c_message_unpack (&talk__descriptor,
                                allocator, len, data);
}
void   talk__free_unpacked
                     (Talk *message,
                      ProtobufCAllocator *allocator)
{
  if(!message)
    return;
  assert(message->base.descriptor == &talk__descriptor);
  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
static const ProtobufCFieldDescriptor id__field_descriptors[1] =
{
  {
    "id",
    1,
    PROTOBUF_C_LABEL_REQUIRED,
    PROTOBUF_C_TYPE_STRING,
    0,   /* quantifier_offset */
    offsetof(ID, id),
    NULL,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
};
static const unsigned id__field_indices_by_name[] = {
  0,   /* field[0] = id */
};
static const ProtobufCIntRange id__number_ranges[1 + 1] =
{
  { 1, 0 },
  { 0, 1 }
};
const ProtobufCMessageDescriptor id__descriptor =
{
  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
  "ID",
  "ID",
  "ID",
  "",
  sizeof(ID),
  1,
  id__field_descriptors,
  id__field_indices_by_name,
  1,  id__number_ranges,
  (ProtobufCMessageInit) id__init,
  NULL,NULL,NULL    /* reserved[123] */
};
static const ProtobufCFieldDescriptor talk__field_descriptors[4] =
{
  {
    "s_id",
    1,
    PROTOBUF_C_LABEL_REQUIRED,
    PROTOBUF_C_TYPE_MESSAGE,
    0,   /* quantifier_offset */
    offsetof(Talk, s_id),
    &id__descriptor,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
  {
    "d_id",
    2,
    PROTOBUF_C_LABEL_REPEATED,
    PROTOBUF_C_TYPE_MESSAGE,
    offsetof(Talk, n_d_id),
    offsetof(Talk, d_id),
    &id__descriptor,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
  {
    "content",
    3,
    PROTOBUF_C_LABEL_REQUIRED,
    PROTOBUF_C_TYPE_STRING,
    0,   /* quantifier_offset */
    offsetof(Talk, content),
    NULL,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
  {
    "timeout",
    4,
    PROTOBUF_C_LABEL_OPTIONAL,
    PROTOBUF_C_TYPE_INT64,
    offsetof(Talk, has_timeout),
    offsetof(Talk, timeout),
    NULL,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
};
static const unsigned talk__field_indices_by_name[] = {
  2,   /* field[2] = content */
  1,   /* field[1] = d_id */
  0,   /* field[0] = s_id */
  3,   /* field[3] = timeout */
};
static const ProtobufCIntRange talk__number_ranges[1 + 1] =
{
  { 1, 0 },
  { 0, 4 }
};
const ProtobufCMessageDescriptor talk__descriptor =
{
  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
  "talk",
  "Talk",
  "Talk",
  "",
  sizeof(Talk),
  4,
  talk__field_descriptors,
  talk__field_indices_by_name,
  1,  talk__number_ranges,
  (ProtobufCMessageInit) talk__init,
  NULL,NULL,NULL    /* reserved[123] */
};
header
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: 2.proto */

#ifndef PROTOBUF_C_2_2eproto__INCLUDED
#define PROTOBUF_C_2_2eproto__INCLUDED

#include <protobuf-c/protobuf-c.h>

PROTOBUF_C__BEGIN_DECLS

#if PROTOBUF_C_VERSION_NUMBER < 1000000
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
#elif 1003002 < PROTOBUF_C_MIN_COMPILER_VERSION
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
#endif


typedef struct _ID ID;
typedef struct _Talk Talk;


/* --- enums --- */


/* --- messages --- */

struct  _ID
{
  ProtobufCMessage base;
  char *id;
};
#define ID__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&id__descriptor) \
    , NULL }


struct  _Talk
{
  ProtobufCMessage base;
  ID *s_id;
  size_t n_d_id;
  ID **d_id;
  char *content;
  protobuf_c_boolean has_timeout;
  int64_t timeout;
};
#define TALK__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&talk__descriptor) \
    , NULL, 0,NULL, NULL, 0, 0 }


/* ID methods */
void   id__init
                     (ID         *message);
size_t id__get_packed_size
                     (const ID   *message);
size_t id__pack
                     (const ID   *message,
                      uint8_t             *out);
size_t id__pack_to_buffer
                     (const ID   *message,
                      ProtobufCBuffer     *buffer);
ID *
       id__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   id__free_unpacked
                     (ID *message,
                      ProtobufCAllocator *allocator);
/* Talk methods */
void   talk__init
                     (Talk         *message);
size_t talk__get_packed_size
                     (const Talk   *message);
size_t talk__pack
                     (const Talk   *message,
                      uint8_t             *out);
size_t talk__pack_to_buffer
                     (const Talk   *message,
                      ProtobufCBuffer     *buffer);
Talk *
       talk__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data);
void   talk__free_unpacked
                     (Talk *message,
                      ProtobufCAllocator *allocator);
/* --- per-message closures --- */

typedef void (*ID_Closure)
                 (const ID *message,
                  void *closure_data);
typedef void (*Talk_Closure)
                 (const Talk *message,
                  void *closure_data);

/* --- services --- */


/* --- descriptors --- */

extern const ProtobufCMessageDescriptor id__descriptor;
extern const ProtobufCMessageDescriptor talk__descriptor;

PROTOBUF_C__END_DECLS


#endif  /* PROTOBUF_C_2_2eproto__INCLUDED */

四、对应结构

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;
};

五、constructor/parser

constructor

size_t pos = 0;
char buf[1024];
char * id = "1234";
char * content = "content";
size_t len = 0;
memset(buf, 0, sizeof(buf));
Talk *talk = (Talk*)buf;
pos += sizeof(*talk);
talk__init(talk);

talk->s_id = buf + pos;
pos += sizeof(*(talk->s_id));
id__init(talk->s_id);

talk->s_id->id = buf + pos;
strcpy(talk->s_id->id, id, strlen(id) + 1);
pos += strlen(id) + 1;

talk->content = buf + pos;
strcpy(talk->s_id->content, content, strlen(content) + 1);
pos += strlen(id) + 1;
/*... do optional filling*/

len = talk__pack(talk, buf);

parser

Talk *unpackedPayload = NULL;
char *msgInfo = NULL;

unpackedPayload = talk__unpack(NULL, msg->len, msg->payload);
msgInfo = protobuf_c_text_to_string((unpackedPayload->base, NULL);
printf("msgInfo %s\n", msgInfo);

/*
unpackedPayload->s_id->id;
unpackedPayload->n_d_id; /*number of */
*/

payload_type__free_unpacked(unpackedPayload);

猜你喜欢

转载自blog.csdn.net/vegeta852/article/details/111935914