Protobuf

欢迎访问我的博客首页


  Protobuf 是 gRPC 的依赖之一,可以直接安装 gRPC

1. 生成源文件


  使用 CMake 编译工具,根据 xxx.proto 生成 xxx.pb.h 和 xxx.pb.cc。整个工程有三个文件,第一个文件是 AddressBook.proto,内容如下。

package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}

  第二个文件是代码文件 main.cpp,内容如下。

#include "AddressBook.pb.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

// 根据用户输入,向地址簿添加一个人的信息。
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_phone();
        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_person());

    {
        // 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;
}

  第三个文件是 CMake 配置文件 CMakeLists.txt,用于根据 xxx.proto 生成 xxx.pb.h 和 xxx.pb.cc,且把代码文件编译成可执行文件。内容如下。

cmake_minimum_required(VERSION 3.2)
project(Protobuf_example)

set(absl_DIR D:/MinGW/libraries/abseil/lib/cmake/absl)
find_package(absl REQUIRED)
set(absl_LIBRARIES
    absl::algorithm
    absl::base
    absl::debugging
    absl::flat_hash_map
    absl::memory
    absl::meta
    absl::numeric
    absl::str_format
    absl::strings
    absl::synchronization
    absl::time
    absl::utility
)

find_package(Protobuf 3.0.0 REQUIRED)
PROTOBUF_GENERATE_CPP(PROTO_HDRS PROTO_SRCS AddressBook.proto)
#message(Protobuf_INCLUDE_DIRS = ${Protobuf_INCLUDE_DIRS})
#message(Protobuf_LIBRARIES = ${Protobuf_LIBRARIES})
#message(PROTO_SRCS = ${PROTO_SRCS})
#message(PROTO_HDRS = ${PROTO_HDRS})

add_executable(${PROJECT_NAME}
	main.cpp
	${PROTO_SRCS}
	${PROTO_HDRS}
)
target_include_directories(${PROJECT_NAME}
    PUBLIC
    ${CMAKE_CURRENT_BINARY_DIR}
    ${PROTOBUF_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME}
    PUBLIC
    ${PROTOBUF_LIBRARIES}
    ${absl_LIBRARIES}
)

   CMake 使用命令 PROTOBUF_GENERATE_CPP 根据 xxx.proto 生成 xxx.pb.h 和 xxx.pb.cc。这个命令来自位于 Protobuf 安装位置 bin 文件夹中的 protoc.exe,因此要确保该路径在环境变量中。

2. 参考


  1. 例子,51CTO,2021。
  2. 例子,CSDN,2020。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值