赞
踩
简介: 无, 懂的都懂
sudo apt install protobuf-compiler protobuf-c-compiler libprotobuf-dev
pkg-config --cflags --libs protobuf
-pthread -lprotobuf -pthread
编译选项: -pthread
链接选项: -lprotobuf -pthread
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; // 添加一个 Person tutorial::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; }
person.proto
syntax = "proto3"; // 使用Protocol Buffers v3语法
package example; // 定义包名,便于组织和避免命名冲突
message Person { // 定义名为Person的消息类型
string name = 1; // 字符串类型字段,标签为1
int32 id = 2; // 整型字段,标签为2
bool is_active = 3; // 布尔型字段,标签为3
repeated 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; }
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.
./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
无
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。