c++ protobuf 使用教程protocol-buffers c++ tutorialhttps://developers.google.com/protocol-buffers/docs/cpptutorialc++ protoc编译器与protobuf库编译
protoc installProtocol Buffers - Google's data interchange format - protobuf/README.md at master · protocolbuffers/protobufhttps://github.com/protocolbuffers/protobuf/blob/master/src/README.md
With protocol buffers, you write a .proto description of the data structure you wish to store. From that, the protocol buffer compiler creates a class that implements automatic encoding and parsing of the protocol buffer data with an efficient binary format. The generated class provides getters and setters for the fields that make up a protocol buffer and takes care of the details of reading and writing the protocol buffer as a unit. importantly, the protocol buffer format supports the idea of extending the format over time in such a way that the code can still read data encoded with the old format.
.proto 文件example与语法介绍
syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
执行命令后生成如下两个文件,两个1000行的文件
addressbook.pb.h, the header which declares your generated classes. a class for each message you specified in addressbook.proto.
addressbook.pb.cc, which contains the implementation of your classes.
官网示例代码,写通讯录文件
#include#include #include #include "addressbook.pb.h" using namespace std; // 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; } } } // 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; }
编译过程
Compiling dependent packages
To compile a package that uses Protocol Buffers, you need to pass various flags to
your compiler and linker. As of version 2.2.0, Protocol Buffers integrates with
pkg-config to manage this. If you have pkg-config installed, then you can invoke
it to get a list of flags like so:
pkg-config --cflags protobuf # print compiler flags pkg-config --libs protobuf # print linker flags pkg-config --cflags --libs protobuf # print both For example: c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
本例的编译命令
pkg-config 命令需要指定protobuf.pc文件所在目录,默认编译生成a.out
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig g++ writer.cpp addressbook.pb.cc `pkg-config --cflags --libs protobuf` -o writer.bin g++ reader.cpp addressbook.pb.cc `pkg-config --cflags --libs protobuf` -o reader.bin
writer.bin test.address 写入通讯录
reader.bin test.address 读取通讯录内容(可以从官方c++ protobuf教程中获取)



