07_c/c++开源库protobuf序列化

devtools/2024/9/23 5:14:44/

1.简介与安装

简介: 无, 懂的都懂

安装

sudo apt install protobuf-compiler protobuf-c-compiler libprotobuf-dev

编译依赖

pkg-config --cflags --libs protobuf

-pthread -lprotobuf -pthread

编译选项: -pthread
链接选项: -lprotobuf -pthread

2.实例

1.代码

实例1

addressbook.proto

syntax = "proto3";package tutorial;message Person {string name = 1;string email = 2;
}message AddressBook {repeated Person people = 1;
}

1_addressbook_protobuf实例.cc

#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"void WriteAddressBook()
{tutorial::AddressBook address_book;// 添加一个 Persontutorial::Person *person = address_book.add_people();person->set_name("Alice");person->set_email("alice@example.com");// 写入到文件std::ofstream output("addressbook.data", std::ios::binary);if (!address_book.SerializeToOstream(&output)){std::cerr << "Failed to write address book." << std::endl;return;}
}void ReadAddressBook()
{tutorial::AddressBook address_book;// 从文件读取std::ifstream input("addressbook.data", std::ios::binary);if (!address_book.ParseFromIstream(&input)){std::cerr << "Failed to read address book." << std::endl;return;}// 输出读取到的人名for (int i = 0; i < address_book.people_size(); ++i){const tutorial::Person &person = address_book.people(i);std::cout << "Name: " << person.name() << ", Email: " << person.email() << std::endl;}
}int main()
{WriteAddressBook();ReadAddressBook();return 0;
}
实例2

person.proto

syntax = "proto3";  // 使用Protocol Buffers v3语法package example;  // 定义包名,便于组织和避免命名冲突message Person {  // 定义名为Person的消息类型string name = 1;  // 字符串类型字段,标签为1int32 id = 2;    // 整型字段,标签为2bool is_active = 3;  // 布尔型字段,标签为3repeated string email = 4;  // 重复字段,表示字符串列表,标签为4
}

2_protobuf_person_序列号到字节.cc

#include "person.pb.h"
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <vector>
using namespace std;// 写入文件
void WriteToFile(const std::string& filename, const example::Person& person) {std::fstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary);if (!person.SerializeToOstream(&output)) {std::cerr << "Failed to write person." << std::endl;}
}// 从文件读取
void ReadFromFile(const std::string& filename, example::Person& person) {std::fstream input(filename, std::ios::in | std::ios::binary);if (!person.ParseFromIstream(&input)) {std::cerr << "Failed to parse person." << std::endl;}
}// 打印反序列化后的数据
void PrintPerson(const example::Person& person) {std::cout << "Name: " << person.name() << std::endl;std::cout << "ID: " << person.id() << std::endl;std::cout << "Is Active: " << person.is_active() << std::endl;// 打印反序列化后的数据for (int i = 0; i < person.email_size(); ++i) {std::cout << "Email " << i + 1 << ": " << person.email(i) << std::endl;}
}int main() {// 创建并填充一个Person对象example::Person person;person.set_name("Alice");person.set_id(123);person.set_is_active(true);person.add_email("alice@example.com");person.add_email("alice.personal@gmail.com");// 1.序列化到 字节uint8_t buf[256] = { 0 };bool ret = person.SerializeToArray(buf, sizeof(buf));// 2.反序列化从 字节example::Person new_person;ret = new_person.ParseFromArray(buf, sizeof(buf));cout << "result ret: " << ret << endl;PrintPerson(new_person);// 3.读写probuf测试WriteToFile("person.bin", person);  // 写入文件ReadFromFile("person.bin", new_person); // 从文件读取PrintPerson(new_person);            // 打印反序列化后的数据return 0;
}

2.scons编译

SConstruct

import os
## 模板2
env = Environment()
env["PROGSUFFIX"] = ".out"            # 可执行后缀.out
env["CCFLAGS"] = " -g3 -O0 -Wall"       # gdb 调试开关
# -pthread -lprotobuf
env.MergeFlags(["!pkg-config protobuf --cflags --libs"])def build_protobuf(file_path):file,file_ext = os.path.splitext(file_path)print(file,file_ext)if file_ext != ".proto":raise f"{file_path} not .proto file"cmd=f"protoc --cpp_out=. {file}.proto"Command(f"{file}.pb.h",file_path,cmd)build_protobuf("addressbook.proto")
env.Program(Split("1_addressbook_protobuf实例.cc addressbook.pb.cc"))
build_protobuf("person.proto")
env.Program(Split("2_protobuf_person_序列号到字节.cc person.pb.cc"))

注意:
protobuf编译方法
protoc --cpp_out=. addressbook.proto

生成 addressbook.pb.cc addressbook.pb.h

scons中并没有直接构建protobuf方法, 可以使用scons Command(target_file, src_file, cmd)
Command使用说明: 如果src_file 时间戳比 target_file 新, 则执行cmd命令
示例: Command("addressbook.pb.h", "addressbook.proto", "rotoc --cpp_out=. addressbook.proto")


scons

scons: Reading SConscript files …
addressbook .proto
person .proto
scons: done reading SConscript files.
scons: Building targets …
protoc --cpp_out=. addressbook.proto
g++ -o 1_addressbook_protobuf实例.o -c -g3 -O0 -Wall -pthread 1_addressbook_protobuf实例.cc
g++ -o addressbook.pb.o -c -g3 -O0 -Wall -pthread addressbook.pb.cc
g++ -o 1_addressbook_protobuf实例.out -pthread 1_addressbook_protobuf实例.o addressbook.pb.o -lprotobuf
protoc --cpp_out=. person.proto
g++ -o 2_protobuf_person_序列号到字节.o -c -g3 -O0 -Wall -pthread 2_protobuf_person_序列号到字节.cc
g++ -o person.pb.o -c -g3 -O0 -Wall -pthread person.pb.cc
g++ -o 2_protobuf_person_序列号到字节.out -pthread 2_protobuf_person_序列号到字节.o person.pb.o -lprotobuf
scons: done building targets.

3.验证测试

./1_addressbook_protobuf实例.out

Name: Alice, Email: alice@example.com

./2_protobuf_person_序列号到字节.out

result ret: 0
Name: Alice
ID: 123
Is Active: 1
Email 1: alice@example.com
Email 2: alice.personal@gmail.com
Name: Alice
ID: 123
Is Active: 1
Email 1: alice@example.com
Email 2: alice.personal@gmail.com

3.其它实例

gitee 在线代码



http://www.ppmy.cn/devtools/14462.html

相关文章

Flink CDC详解

文章目录 Flink CDC一 CDC简介1.1 CDC定义1.2 CDC应用场景1.3 CDC实现机制1.4 开源CDC工具对比 二 Flink CDC简介2.1 Flink CDC介绍2.2 Flink CDC Connector(连接器)2.3 Flink CDC && Flink版本2.4 Flink CDC特点 三 Flink CDC发展3.1 发展历程3.2 背景Dynamic Table &…

深入解读Dubbo:微服务RPC框架的佼佼者

在微服务盛行的今天&#xff0c;RPC&#xff08;远程过程调用&#xff09;框架的重要性日益凸显。Dubbo&#xff0c;作为阿里巴巴公司开源的一款高性能、轻量级的Java RPC框架&#xff0c;已经成为众多企业构建微服务架构的首选。作为一名资深的架构师&#xff0c;我深知Dubbo在…

JenKins使用(Linux)

一、准备工作 1、Linux中装好JDK、Maven、Git这三个环境 &#xff08;1&#xff09;配置JDK的环境变量 &#xff08;2&#xff09;配置Maven的Setting.xml文件和环境变 &#xff08;3&#xff09;Git就不需要配置环境变量了 2、安装JenKins&#xff0c;注意网上说 JenKins…

vue 实现左侧导航栏,右侧锚点定位滚动到指定位置(超简单方法)

项目截图&#xff1a; 实现方法&#xff1a; 点击左侧菜单根据元素id定位到可视内容区域。 浏览器原生提供了一种方法scrollIntoView 。 通过scrollIntoView方法可以把元素滚动到可视区域内。 behavior: "smooth"是指定滚动方式为平滑效果。 具体代码如下&#xf…

计算机网络——应用层协议(1)

在这篇文章初识网络中&#xff0c;我介绍了关于计算机网络的相关知识&#xff0c;以及在这两篇文章中Socket编程和Socket编程——tcp&#xff0c;介绍了使用套接字在两种协议下的网络间通信方式。本篇文章中我将会进一步介绍网络中网络协议的部分&#xff0c;而这将会从应用层开…

udp/tcp错误总结

udp tcp——多进程 tcp——多线程 tcp——线程池 tcp——守护进程 &#x1f386;udp  ✨pthread_create 错误总结  ✨LockGuard错误总结  ✨服务端需要写成多线程  ✨客户端也需要写成多线程  ✨多线程调试工具 &#x1f386;tcp  ✨tcp独有调试工具——telnet  ✨Threa…

芯科科技大大简化面向无电池物联网的能量采集产品的开发

芯科科技推出其迄今最高能量效率且支持能量采集功能的无线SoC 中国&#xff0c;北京 – 2024年4月22日 – 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;…

quasar框架切换Tab页使用<keep-alive>缓存

写法1 : 使用quasar的q-tabs组件使用方法 //布局样式根据需求自己设置 <template><div class"all-Tabs"><q-tabs v-model"activeTabName" update:model-value"selectedChange"><q-tabv-for"(item, index) in cardAr…