赞
踩
protobuf
提供了一些发布的版本,可以从里面下载指定语言的压缩包。
例如:
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.7/protobuf-cpp-3.21.7.zip
unzip protobuf-cpp-3.21.7.zip
在上面解压的文件夹下,是有一个README.md
文件的,里面介绍了安装的方式,主要是:
To build protobuf from source, the following tools are needed:
On Ubuntu/Debian, you can install them with:
sudo apt-get install autoconf automake libtool curl make g++ unzip
To build and install the C++ Protocol Buffer runtime and the Protocol
Buffer compiler (protoc
) execute the following:
./configure
make -j$(nproc) # $(nproc) ensures it uses all cores for compilation
make check
sudo make install
sudo ldconfig # refresh shared library cache.
By default, the package will be installed to /usr/local
.
可以在终端上输入protoc --version
查看安装成功与否。
示例主要来自文件夹examples
下的addressbook.proto
。
protobuf
源文件,addressbook.proto
// [START declaration] syntax = "proto3"; package tutorial; import "google/protobuf/timestamp.proto"; // [END declaration] // [START messages] message Person { string name = 1; int32 id = 2; // Unique ID number for this person. string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; google.protobuf.Timestamp last_updated = 5; } // Our address book file is just one of these. message AddressBook { repeated Person people = 1; } // [END messages]
这个文件主要的作用是定义了protobuf
结构。
可以看到最后面,电话本(AddressBook)里面定义了
Person
结构,其repeated
代表了电话本可以包含多个Person
。
proto
源文件在源文件目录下执行以下编译命令:
protoc -I=. --cpp_out=. addressbook.proto
执行完后,会生成一个.cc和一个.h文件
生成的文件主要包含了结构体成员设置和格式转换的接口,下面展示一下如何使用。
testwrite.cc
:#include <ctime> #include <fstream> #include <google/protobuf/util/time_util.h> #include <iostream> #include <string> #include "addressbook.pb.h" using namespace std; using google::protobuf::util::TimeUtil; // This function fills in a Person message based on user input. void PromptForAddress(tutorial::Person *person) { cout << "Enter person ID number: "; int id; cin >> id; person->set_id(id); cin.ignore(256, '\n'); cout << "Enter name: "; getline(cin, *person->mutable_name()); cout << "Enter email address (blank for none): "; string email; getline(cin, email); if (!email.empty()) { person->set_email(email); } while (true) { cout << "Enter a phone number (or leave blank to finish): "; string number; getline(cin, number); if (number.empty()) { break; } tutorial::Person::PhoneNumber *phone_number = person->add_phones(); phone_number->set_number(number); cout << "Is this a mobile, home, or work phone? "; string type; getline(cin, type); if (type == "mobile") { phone_number->set_type(tutorial::Person::MOBILE); } else if (type == "home") { phone_number->set_type(tutorial::Person::HOME); } else if (type == "work") { phone_number->set_type(tutorial::Person::WORK); } else { cout << "Unknown phone type. Using default." << endl; } } *person->mutable_last_updated() = TimeUtil::SecondsToTimestamp(time(NULL)); } // Main function: Reads the entire address book from a file, // adds one person based on user input, then writes it back out to the same // file. int main(int argc, char *argv[]) { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. GOOGLE_PROTOBUF_VERIFY_VERSION; if (argc != 2) { cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; return -1; } tutorial::AddressBook address_book; { // Read the existing address book. fstream input(argv[1], ios::in | ios::binary); if (!input) { cout << argv[1] << ": File not found. Creating a new file." << endl; } else if (!address_book.ParseFromIstream(&input)) { cerr << "Failed to parse address book." << endl; return -1; } } // Add an address. PromptForAddress(address_book.add_people()); { // Write the new address book back to disk. fstream output(argv[1], ios::out | ios::trunc | ios::binary); if (!address_book.SerializeToOstream(&output)) { cerr << "Failed to write address book." << endl; return -1; } } // Optional: Delete all global objects allocated by libprotobuf. google::protobuf::ShutdownProtobufLibrary(); return 0; }
通过以下命令编译,testread
同理
g++ testwrite.cc addressbook.pb.cc -o testwrite -lprotobuf
运行可执行文件:
./testwrite addressbook.data
输入信息即可,查看addressbook.data
,可以看到打包的数据。
testread.cc
:#include <fstream> #include <google/protobuf/util/time_util.h> #include <iostream> #include <string> #include "addressbook.pb.h" using namespace std; using google::protobuf::util::TimeUtil; // Iterates though all people in the AddressBook and prints info about them. void ListPeople(const tutorial::AddressBook &address_book) { for (int i = 0; i < address_book.people_size(); i++) { const tutorial::Person &person = address_book.people(i); cout << "Person ID: " << person.id() << endl; cout << " Name: " << person.name() << endl; if (person.email() != "") { cout << " E-mail address: " << person.email() << endl; } for (int j = 0; j < person.phones_size(); j++) { const tutorial::Person::PhoneNumber &phone_number = person.phones(j); switch (phone_number.type()) { case tutorial::Person::MOBILE: cout << " Mobile phone #: "; break; case tutorial::Person::HOME: cout << " Home phone #: "; break; case tutorial::Person::WORK: cout << " Work phone #: "; break; default: cout << " Unknown phone #: "; break; } cout << phone_number.number() << endl; } if (person.has_last_updated()) { cout << " Updated: " << TimeUtil::ToString(person.last_updated()) << endl; } } } // Main function: Reads the entire address book from a file and prints all // the information inside. int main(int argc, char *argv[]) { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. GOOGLE_PROTOBUF_VERIFY_VERSION; if (argc != 2) { cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl; return -1; } tutorial::AddressBook address_book; { // Read the existing address book. fstream input(argv[1], ios::in | ios::binary); if (!address_book.ParseFromIstream(&input)) { cerr << "Failed to parse address book." << endl; return -1; } } ListPeople(address_book); // Optional: Delete all global objects allocated by libprotobuf. google::protobuf::ShutdownProtobufLibrary(); return 0; }
运行可执行文件testread,读出addressbook.data中的信息,也就是反序列化。
./testread addressbook.data
output:
Person ID: 1
Name: wzm
E-mail address: 12345
Mobile phone #: 11111
Mobile phone #: sfafsa
Mobile phone #: qqwq
Mobile phone #: saf
Updated: 2022-09-30T08:37:46Z
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。