安裝和使用protobuf-c

介紹

Protocol Buffers,是Google公司開發(fā)的一種數(shù)據(jù)描述語言,類似于XML能夠?qū)⒔Y(jié)構(gòu)化數(shù)據(jù)序列化,可用于數(shù)據(jù)存儲、通信協(xié)議等方面。它不依賴于語言和平臺并且可擴(kuò)展性極強(qiáng)。

同XML相比,Protocol buffers在序列化結(jié)構(gòu)化數(shù)據(jù)方面有許多優(yōu)點:
1. 更簡單
2. 數(shù)據(jù)描述文件只需原來的1/10至1/3
3. 解析速度是原來的20倍至100倍
4. 減少了二義性
5. 生成了更容易在編程中使用的數(shù)據(jù)訪問
6.支持多種編程語言
(轉(zhuǎn)自百度百科)

  • 完整代碼放到我的github下了

安裝

這里我使用的是 protobuf-c,在安裝 protobuf-c 之前需要安裝 protobuf 。

安裝protobuf

首先安裝依賴 sudo apt-get install autoconf automake libtool curl make g++ unzip

git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git submodule update --init --recursive
./autogen.sh
./configure
make
make check  # make check 失敗的話沒關(guān)系,繼續(xù)下面的安裝
sudo make install
sudo ldconfig

安裝protobuf-c

首先安裝依賴sudo apt-get install pkg-config pkgconf

git clone https://github.com/protobuf-c/protobuf-c.git
./autogen.sh && ./configure && make && make install

到這里就已經(jīng)安裝好 protobufprotobuf-c

使用protobuf-c

編輯文件student.proto 這里用的是proto2(建議新手直接上 proto3
這里以 student 為例子

syntax = "proto2";

message Student {
    optional string name = 1;
}

命令protoc --c_out=. student.proto
生成.c.h文件 student.pb-c.c student.pb-c.h

不要太關(guān)注下面的兩個文件

  • 下面是生成的student.pb-c.h
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: student.proto */

#ifndef PROTOBUF_C_student_2eproto__INCLUDED
#define PROTOBUF_C_student_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 1003003 < 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 _Student Student;


/* --- enums --- */


/* --- messages --- */

struct  _Student
{
  ProtobufCMessage base;
  char *name;
};
#define STUDENT__INIT \
 { PROTOBUF_C_MESSAGE_INIT (&student__descriptor) \
    , 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_C_student_2eproto__INCLUDED */
  • 下面是生成的student.pb-c.c
// student.pb-c.c
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: student.proto */

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

#include "student.pb-c.h"
void   student__init
                     (Student         *message)
{
  static const Student init_value = STUDENT__INIT;
  *message = init_value;
}
size_t student__get_packed_size
                     (const Student *message)
{
  assert(message->base.descriptor == &student__descriptor);
  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t student__pack
                     (const Student *message,
                      uint8_t       *out)
{
  assert(message->base.descriptor == &student__descriptor);
  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t student__pack_to_buffer
                     (const Student *message,
                      ProtobufCBuffer *buffer)
{
  assert(message->base.descriptor == &student__descriptor);
  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
}
Student *
       student__unpack
                     (ProtobufCAllocator  *allocator,
                      size_t               len,
                      const uint8_t       *data)
{
  return (Student *)
     protobuf_c_message_unpack (&student__descriptor,
                                allocator, len, data);
}
void   student__free_unpacked
                     (Student *message,
                      ProtobufCAllocator *allocator)
{
  if(!message)
    return;
  assert(message->base.descriptor == &student__descriptor);
  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
static const ProtobufCFieldDescriptor student__field_descriptors[1] =
{
  {
    "name",
    1,
    PROTOBUF_C_LABEL_OPTIONAL,
    PROTOBUF_C_TYPE_STRING,
    0,   /* quantifier_offset */
    offsetof(Student, name),
    NULL,
    NULL,
    0,             /* flags */
    0,NULL,NULL    /* reserved1,reserved2, etc */
  },
};
static const unsigned student__field_indices_by_name[] = {
  0,   /* field[0] = name */
};
static const ProtobufCIntRange student__number_ranges[1 + 1] =
{
  { 1, 0 },
  { 0, 1 }
};
const ProtobufCMessageDescriptor student__descriptor =
{
  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
  "Student",
  "Student",
  "Student",
  "",
  sizeof(Student),
  1,
  student__field_descriptors,
  student__field_indices_by_name,
  1,  student__number_ranges,
  (ProtobufCMessageInit) student__init,
  NULL,NULL,NULL    /* reserved[123] */
};

在代碼里使用

編輯文件 student.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.pb-c.h"

#define NAME_LEN 32

int main() {
    Student stu = STUDENT__INIT; // 初始化
    void *buf = NULL;
    unsigned int len;
    Student *msg = NULL;

    stu.name = (char*)malloc(NAME_LEN);
    stu.name = "test";

    len = student__get_packed_size(&stu);  // 算出大小
    printf("size of Student info : %u\n", len);
    buf = malloc(len);
    student__pack(&stu, buf); // 打包

    msg = student__unpack(NULL, len, buf); // 解包
    printf("msg name : %s\n", msg->name);

    student__free_unpacked(msg, NULL); // 釋放空間

    free(buf);
    return 0;
}

編譯

編譯 gcc student.c student.pb-c.c -o student -lprotobuf-c
需要連接 protobuf-c
輸出:

size of Student info : 6
msg name : test

2020.3.2 16:40 廣州

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容