Protobuf使用实例

前面章节已经讲述了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

猜你喜欢

转载自blog.csdn.net/u012414189/article/details/84074463