0

0

怎样在C++中解析协议缓冲区_Protobuf集成指南

穿越時空

穿越時空

发布时间:2025-06-18 15:12:02

|

307人浏览过

|

来源于php中文网

原创

c++++中解析协议缓冲区,首先需要使用protobuf编译器生成c++代码,然后使用protobuf库提供的api进行读写操作。1. 定义.proto文件并使用protoc编译生成.pb.h和.pb.cc文件;2. 在c++项目中包含生成的文件,并使用生成的类创建、读取、写入数据;3. 编译时链接protobuf库以确保程序正常运行;4. 对于嵌套消息和枚举类型,在.proto文件中定义后可在c++中通过类名和作用域操作符访问;5. 优化性能可通过避免拷贝、使用arena分配器、延迟解析、启用generated_code_info及选择合适序列化格式实现;6. 处理版本兼容性问题应添加字段时指定默认值,删除字段时保留编号并标记为reserved,重命名字段时使用deprecated选项,添加枚举值时避免冲突,修改消息类型时保持兼容性。

怎样在C++中解析协议缓冲区_Protobuf集成指南

在C++中解析协议缓冲区,简单来说,你需要protobuf编译器生成C++代码,然后使用protobuf库提供的API来读写数据。这涉及到定义.proto文件,编译它,以及在你的C++项目中使用生成的类。

怎样在C++中解析协议缓冲区_Protobuf集成指南

解决方案

首先,你需要安装protobuf编译器和C++库。在Linux上,这通常可以通过包管理器完成,例如apt-get install protobuf-compiler libprotobuf-dev。在Windows上,你可能需要从protobuf的GitHub仓库下载预编译的二进制文件,或者使用vcpkg或Chocolatey等包管理器。

怎样在C++中解析协议缓冲区_Protobuf集成指南

接下来,定义你的.proto文件。例如,一个简单的地址簿条目可能如下所示:

立即学习C++免费学习笔记(深入)”;

怎样在C++中解析协议缓冲区_Protobuf集成指南
syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

保存为addressbook.proto。然后,使用protobuf编译器生成C++代码:

protoc --cpp_out=. addressbook.proto

这会生成addressbook.pb.haddressbook.pb.cc文件。将这些文件添加到你的C++项目中。

现在,你可以使用生成的类来读写数据。例如,读取一个AddressBook

#include "addressbook.pb.h"
#include 
#include 

using namespace std;
using namespace tutorial;

int main() {
  AddressBook address_book;

  {
    // Read the existing address book.
    fstream input("addressbook.data", ios::in | ios::binary);
    if (!address_book.ParseFromIstream(&input)) {
      cerr << "Failed to parse address book." << endl;
      return -1;
    }
  }

  for (int i = 0; i < address_book.people_size(); ++i) {
    const Person& person = address_book.people(i);
    cout << "Person ID: " << person.id() << endl;
    cout << "  Name: " << person.name() << endl;
    if (person.has_email()) {
      cout << "  E-mail: " << person.email() << endl;
    }

    for (int j = 0; j < person.phones_size(); ++j) {
      const Person::PhoneNumber& phone_number = person.phones(j);

      switch (phone_number.type()) {
        case Person::MOBILE:
          cout << "  Mobile phone #: ";
          break;
        case Person::HOME:
          cout << "  Home phone #: ";
          break;
        case Person::WORK:
          cout << "  Work phone #: ";
          break;
      }
      cout << phone_number.number() << endl;
    }
  }

  return 0;
}

同样,写入一个AddressBook

10Web
10Web

AI驱动的WordPress网站自动构建器,托管和页面速度助推器

下载
#include "addressbook.pb.h"
#include 
#include 

using namespace std;
using namespace tutorial;

int main() {
  AddressBook address_book;

  // Add a person.
  Person* person = address_book.add_people();
  person->set_name("John Doe");
  person->set_id(1234);
  person->set_email("johndoe@example.com");

  Person::PhoneNumber* phone = person->add_phones();
  phone->set_number("555-4321");
  phone->set_type(Person::HOME);

  {
    // Write the new address book back to disk.
    fstream output("addressbook.data", ios::out | ios::trunc | ios::binary);
    if (!address_book.SerializeToOstream(&output)) {
      cerr << "Failed to write address book." << endl;
      return -1;
    }
  }

  return 0;
}

编译并运行这些代码,确保链接protobuf库。例如,使用g++:

g++ -o read_addressbook read_addressbook.cc addressbook.pb.cc -lprotobuf
g++ -o write_addressbook write_addressbook.cc addressbook.pb.cc -lprotobuf

如何处理Protobuf中的嵌套消息和枚举类型?

嵌套消息和枚举类型在.proto文件中定义后,protobuf编译器会为它们生成相应的C++类和枚举。在C++代码中,你可以像访问普通类和枚举一样访问它们。例如,在上面的Person消息中,PhoneNumber是一个嵌套消息,PhoneType是一个枚举。你可以使用Person::PhoneNumberPerson::PhoneType来引用它们。

在设置嵌套消息的值时,你需要先获取嵌套消息的指针,然后设置其字段。例如:

Person* person = address_book.add_people();
Person::PhoneNumber* phone = person->add_phones();
phone->set_number("555-4321");
phone->set_type(Person::HOME); // 使用 Person::HOME 而不是简单的 HOME

处理枚举类型时,直接使用枚举值即可。protobuf编译器会确保类型安全。

优化Protobuf解析性能的策略有哪些?

Protobuf的解析性能通常已经很好,但仍然有一些策略可以进一步优化:

  1. 避免不必要的拷贝:尽量使用ParseFromIstreamSerializeToOstream直接从流中读写数据,而不是先将数据加载到内存中再进行解析。
  2. 使用arena分配器arena分配器可以减少内存分配和释放的开销,特别是在处理大量消息时。需要在.proto文件中启用arena支持,并在C++代码中使用Arena类。
  3. 延迟解析:如果只需要访问消息的部分字段,可以使用延迟解析。这可以避免解析整个消息,从而提高性能。但是,延迟解析会增加代码的复杂性。
  4. 使用generated_code_info:在编译.proto文件时,可以生成generated_code_info文件。这个文件包含了关于生成的代码的信息,可以用于优化性能分析。
  5. 使用合适的序列化格式:除了默认的二进制格式,protobuf还支持JSON格式。JSON格式更易于阅读和调试,但性能通常不如二进制格式。

如何处理Protobuf的版本兼容性问题?

Protobuf的设计目标之一是提供良好的版本兼容性。这意味着即使.proto文件发生变化,旧的代码仍然可以读取新的数据,新的代码也可以读取旧的数据。但是,仍然需要注意一些事项:

  1. 添加字段:添加新字段时,应该为字段指定默认值。这样,旧的代码在读取新的数据时,如果没有找到新字段,就会使用默认值。
  2. 删除字段:删除字段时,应该保留字段编号,并将其标记为reserved。这样,可以防止新的字段使用相同的编号,从而避免冲突。
  3. 重命名字段:重命名字段时,应该使用[deprecated=true]选项标记旧的字段,并添加新的字段。这样,旧的代码仍然可以读取旧的字段,新的代码可以使用新的字段。
  4. 枚举类型:添加新的枚举值时,应该确保新的枚举值不会与旧的枚举值冲突。
  5. 消息类型:修改消息类型时,应该尽量保持兼容性。例如,可以添加新的字段,但不要删除或重命名字段。

总的来说,protobuf提供了一套强大的工具和约定,可以帮助你处理版本兼容性问题。但是,仍然需要仔细设计你的.proto文件,并进行充分的测试。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

403

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

528

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

307

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

521

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1058

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

751

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

420

2023.08.02

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.8万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号