cen's blog cen's blog
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • C++学习
    • C++数据结构
    • MySQL
    • Linux
    • 网络编程
算法
  • Git
  • ProtoBuf
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

cen

十年饮冰,难凉热血
首页
  • 编程文章

    • markdown使用
  • 学习笔记

    • C++学习
    • C++数据结构
    • MySQL
    • Linux
    • 网络编程
算法
  • Git
  • ProtoBuf
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • Git
  • ProtoBuf
    • 初步认识
    • 安装
    • 快速上手
    • 类型对比
    • 编译
    • 序列化与反序列化
    • 使用示例
  • 工具
cen
2025-09-28
目录

ProtoBuf

# 初步认识

Protocol Buffers 是一种语言中立、平台中立、可扩展的结构化数据序列化机制。类似于 JSON,但更小更快,并且能生成原生语言绑定。只需一次性定义好想要的数据结构,然后就可以使用专门生成的源代码,轻松地从各种数据流中读写你的结构化数据,并支持多种语言。

  • 跨语言、跨平台:即 ProtoBuf 支持 Java、C++、Python?等多种语言,支持多个平台
  • 高效:即比 XML 更小、更快、更为简单
  • 扩展性、兼容性好:更新数据结构,而不影响和破坏原有的旧程序

# 安装

  • Windows: protobuf (opens new window),下载压缩包,添加环境变量,protoc --version查看版本即可

  • Linux:

  1. wget https://github.com/protocolbuffers/protobuf/releases/download/v21.11/protobuf-cpp-3.21.11.zip:表示下载 21.11 版本的支持 C++语言的 protobuf
  2. unzip 解压压缩包
  3. 安装
# 执行autogen.sh
./autogen.sh

# 执行configure
./configure --prefix=/usr/local/protobuf
# 安装
make
sudo make install
1
2
3
4
5
6
7
8
  1. protoc --version检查版本

当然也可以用包管理器来直接安装

# 快速上手

  • 指定版本: Protocol Buffers 语言版本 3,简称 proto3,是 .proto 文件最新的语法版本。proto3 简化了 Protocol Buffers 语言,易于使用。
// 指定proto版本
syntax = "proto3";
1
2
  • package: package 是一个可选的声明符,能表示 .proto 文件的命名空间,是为了避免我们定义的消息出现冲突。
// 包名
package contacts;
1
2
  • message: message 就是要定义的结构化对象,可以给这个结构化对象中定义其对应的属性内容。字段定义格式为:字段类型 字段名 = 字段唯一编号
    • 字段名称命名规范:全小写字母,多个字母之间⽤_连接
    • 字段类型分为:标量数据类型和特殊类型(包括枚举、其他消息类型等)
    • 字段唯一编号:用来标识字段,一旦开始使用就不能够再改变
message Person {
    int32 age = 1;
    bytes name = 2;
}
1
2
3
4

# 类型对比

Protobuf 类型 C++ 类型 说明
double double 双精度浮点数
float float 单精度浮点数
int32 int32 可变长编码,对负数效率低
int64 int64 可变长编码,对负数效率低
uint32 uint32 可变长编码
uint64 uint64 可变长编码
bool bool 布尔值
bytes std::string 任意字节序列

# 编译

编译命令行格式为:protoc [--proto_path=IMPORT_PATH] --cpp_out=DST_DIR path/to/file.proto

  • --proto_path 指定被编译的 .proto 文件所在目录,可简写成 -I IMPORT_PATH。如不指定该参数,则在当前目录进行搜索。当 import 其他 .proto 文件时,同时也不在当前目录下,这时就要用 -I 来指定搜索目录
  • --cpp_out= 指编译后的文件为 C++ 文件
  • OUT_DIR 编译后生成文件的目标路径
  • path/to/file.proto 要编译的 .proto 文件路径
[root@VM-4-9-opencloudos lesson08-protobuf]# protoc --cpp_out=. contacts.proto
[root@VM-4-9-opencloudos lesson08-protobuf]# ls
contacts.pb.cc  contacts.pb.h  contacts.proto
1
2
3

其中,提供了包括序列化、反序列化等一系列接口

# 序列化与反序列化

// 序列化:
// 将类对象中的数据序列化为字符串, c++ 风格的字符串, 参数是一个传出参数
bool SerializeToString(std::string* output) const;
// 将类对象中的数据序列化为字符串, c 风格的字符串, 参数 data 是一个传出参数
bool SerializeToArray(void* data, int size) const;

// 反序列化:
bool ParseFromString(const std::string& data) ;
bool ParseFromArray(const void* data, int size);
1
2
3
4
5
6
7
8
9

# 使用示例

#include <iostream>
#include "contacts.pb.h"

using namespace std;

int main() {
    string personStr;
    contacts::Person person1;
    contacts::Person person2;
    person1.set_age(22);
    person1.set_name("zahngsan");

    person1.SerializeToString(&personStr);
    cout << "Serialize:" << personStr << endl;

    person2.ParseFromString(personStr);
    cout << person2.age() << " " << person2.name() << endl;
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上次更新: 2025/11/11, 22:03:54
Git

← Git

最近更新
01
动态规划
11-08
02
Git
09-28
03
Reactor
09-27
更多文章>
Theme by Vdoing | Copyright © 2024-2025 京ICP备2020044002号-3 京公网安备11010502056119号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式