• Protobuf简介及其在C++中的使用


    什么是Protobuf

    ProtobufProtocol Buffers)是由Google开发的一种语言中立、平台中立、可扩展的序列化数据格式。它能够将结构化数据序列化并通过网络进行传输或存储。Protobuf提供了高效的二进制格式,比XML或JSON更加紧凑和高效。

    为什么选择Protobuf?

    1. 高效性:二进制格式相比文本格式更为紧凑,解析速度更快。
    2. 跨语言支持:Protobuf支持多种编程语言,包括C++、Java、Python、Go等。
    3. 向后兼容:在数据结构发生变化时,可以保持向后兼容性。
    4. 灵活性:可以定义复杂的数据结构,支持嵌套和重复字段。

    Protobuf的安装与配置见 : protobuf安装与配置

    定义Protobuf消息

    在使用Protobuf之前,我们需要定义消息格式。通常将这些定义写在.proto文件中。以下是一个简单的示例:

    1. syntax = "proto3";
    2. message Person {
    3. string name = 1;
    4. int32 id = 2;
    5. string email = 3;
    6. }

    在这个示例中,我们定义了一个Person消息,包含nameidemail三个字段。

    使用Protobuf编译器生成C++代码

    定义好.proto文件后,我们需要使用protoc编译器将其转换为C++代码:

    protoc --cpp_out=. person.proto
    

    这将生成两个文件:person.pb.hperson.pb.cc,它们包含了Protobuf消息类的定义和实现。

    在C++中使用Protobuf

    接下来,我们在C++项目中包含生成的头文件并使用Protobuf消息。以下是一个简单的示例:

    1. #include
    2. #include "person.pb.h"
    3. int main() {
    4. // 创建Person对象
    5. Person person;
    6. person.set_name("John Doe");
    7. person.set_id(123);
    8. person.set_email("johndoe@example.com");
    9. // 序列化到字符串
    10. std::string serialized_data;
    11. person.SerializeToString(&serialized_data);
    12. // 反序列化
    13. Person deserialized_person;
    14. deserialized_person.ParseFromString(serialized_data);
    15. // 输出反序列化后的数据
    16. std::cout << "Name: " << deserialized_person.name() << std::endl;
    17. std::cout << "ID: " << deserialized_person.id() << std::endl;
    18. std::cout << "Email: " << deserialized_person.email() << std::endl;
    19. return 0;
    20. }

    完整示例:从定义到使用

    为了更好地理解,我们将从头到尾演示一个完整的示例。

    1. // main.cpp
    2. #include
    3. #include
    4. #include "person.pb.h"
    5. using namespace std;
    6. // 序列化 Person 对象到文件
    7. void serializePerson(const Person& person, const string& filename) {
    8. fstream output(filename, ios::out | ios::trunc | ios::binary);
    9. if (!person.SerializeToOstream(&output)) {
    10. cerr << "Failed to write person." << endl;
    11. }
    12. }
    13. // 从文件反序列化 Person 对象
    14. Person deserializePerson(const string& filename) {
    15. Person person;
    16. fstream input(filename, ios::in | ios::binary);
    17. if (!person.ParseFromIstream(&input)) {
    18. cerr << "Failed to read person." << endl;
    19. }
    20. return person;
    21. }
    22. int main() {
    23. // 初始化 Protocol Buffers 库
    24. GOOGLE_PROTOBUF_VERIFY_VERSION;
    25. // 创建并设置 Person 对象
    26. Person person;
    27. person.set_name("John Doe");
    28. person.set_id(123);
    29. person.set_email("john.doe@example.com");
    30. // 序列化到文件
    31. const string filename = "person.bin";
    32. serializePerson(person, filename);
    33. // 从文件反序列化
    34. Person new_person = deserializePerson(filename);
    35. // 输出反序列化后的数据
    36. cout << "Name: " << new_person.name() << endl;
    37. cout << "ID: " << new_person.id() << endl;
    38. cout << "Email: " << new_person.email() << endl;
    39. // 清理 Protocol Buffers 库
    40. google::protobuf::ShutdownProtobufLibrary();
    41. return 0;
    42. }

    总结

    我们从定义Protobuf消息开始,逐步讲解了如何使用Protobuf编译器生成C++代码,并在C++项目中使用这些生成的代码进行数据序列化和反序列化。

    想获取更加详细的用法 : 课件.doc(见文章顶部)

  • 相关阅读:
    并行计算技术与SIMD、SIMT
    深度学习的模型剪枝
    计算机毕业设计之java+javaweb的外婆家网上订餐平台
    webrtc gcc算法(1)
    华为数通方向HCIP-DataCom H12-821题库(多选题:01-20)
    JVM虚拟机学习笔记之-5. 字节码执行引擎
    mysql 数据库使用分享(多图解析)
    Docker简介
    firewalld常用的基础配置
    ElementUI的bug/方案/使用技巧合集,持续更新(最新22-7-4)
  • 原文地址:https://blog.csdn.net/m0_74091159/article/details/139336909