前面章节已经讲述了protobuf的理解,这里直接开门见山,给出一个实,来具体看下是如何使用的。
本案例参考博客:
google protobuf安装与使用
案例的主要功能(google提供的基本案例)
该程序示例的大致功能是,定义一个Persion结构体和存放Persion的AddressBook,然后一个写程序向一个文件写入该结构体信息,另一个程序从文件中读出该信息并打印到输出中。
1.addressbook.proto文件
package tutorial;
message Persion {
required string name = 1;
required int32 age = 2;
}
message AddressBook {
repeated Persion persion = 1;
}
这里需要注意的是:required表示的必须项,也就是定义的这些项必须被填充,如果想不被填充,protobuf也提供了optional的选项。
完成addressbook.proto文件的编写,然后进行编译,注意这里编译需要使用protobuf的编译器,执行命令如下:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
示例中执行命令
protoc --cpp_out=/tmp addressbook.proto
会在/tmp中生成文件addressbook.pb.h和addressbook.pb.cc。
2 write.cpp文件,向文件中写入AddressBook信息,该文件是二进制的
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;
void PromptForAddress(tutorial::Persion *persion) {
cout << "Enter persion name:" << endl;
string name;
cin >> name;
persion->set_name(name);
int age;
cin >> age;
persion->set_age(age);
}
int main(int argc, char **argv) {
//GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
return -1;
}
tutorial::AddressBook 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 << "Filed to parse address book." << endl;
return -1;
}
}
// Add an address
PromptForAddress(address_book.add_persion());
{
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;
}
同样编译,执行以下编译命令:
g++ addressbook.pb.cc write.cpp -o write `pkg-config --cflags --libs protobuf`
注意,我在这里编译的时候会报错,可能是代码本身头文件的问题,可能是pkgconfig的问题,这个问题可以参考这篇博客解决:Google-Protocol Buffer例子编译问题
3. read.cpp文件,从文件中读出AddressBook信息并打印
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;
void ListPeople(const tutorial::AddressBook& address_book) {
for (int i = 0; i < address_book.persion_size(); i++) {
const tutorial::Persion& persion = address_book.persion(i);
cout << persion.name() << " " << persion.age() << endl;
}
}
int main(int argc, char **argv) {
//GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
{
fstream input(argv[1], ios::in | ios::binary);
if (!address_book.ParseFromIstream(&input)) {
cerr << "Filed to parse address book." << endl;
return -1;
}
input.close();
}
ListPeople(address_book);
// Optional: Delete all global objects allocated by libprotobuf.
//google::protobuf::ShutdownProtobufLibrary();
return 0;
}
同样,执行和write一样的编译命令,如下:
g++ addressbook.pb.cc read.cpp -o read `pkg-config --cflags --libs protobuf`
4.执行程序结果
参考文献:
https://www.cnblogs.com/luoxn28/p/5303517.html
https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html