Google 官网上的一个典型例子

(1)定义 proto 文件

// addressbook.protopackage tutorial;  // package声明符message Person {required string name = 1;required int32 id = 2;optional string email = 3;// 枚举类型enum PhoneType {MOBILE = 0; // 如果是proto3,则首成员必须是0HOME = 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;
}

proto 文件相当于 data schema,规定了数据如何组织。

(2)编译 proto 文件

使用 protoc compiler 来编译定义好的 proto 文件,生成 API 头文件和源代码,命令为:

protoc -I=/protofile/directory -cpp_out=/output/directory /path/to/protofile
比如:
protoc -I=/data/zyy/usr/file/ --cpp_out=/data/zyy/usr/file/ /data/zyy/usr/file/addressbook.proto
  1. -I 之后为 proto 文件的源路径
  2. --cpp_out 后面为编译生成的 .h.cc 文件的路径
  3. 最后是 proto 文件的路径
  4. 编译之后会生成 addressbook.pb.h 头文件和 addressbook.pb.cc 源文件,其中包含了大量的接口函数,用户可以利用这些接口函数获取和改变某个 field 的值。

生成文件的接口函数:

// name
inline bool has_name() const;
inline void clear_name();
inline const ::std::string& name() const;  //getter
inline void set_name(const ::std::string& value);  //setter
inline void set_name(const char* value);  //setter
inline ::std::string* mutable_name();// email
inline bool has_email() const;
inline void clear_email();
inline const ::std::string& email() const; //getter
inline void set_email(const ::std::string& value);  //setter
inline void set_email(const char* value);  //setter
inline ::std::string* mutable_email();// phone
inline int phone_size() const;
inline void clear_phone();
inline const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phone() const;
inline ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phone();
inline const ::tutorial::Person_PhoneNumber& phone(int index) const;
inline ::tutorial::Person_PhoneNumber* mutable_phone(int index);
inline ::tutorial::Person_PhoneNumber* add_phone();

发现每个类都有对应的 setter 和 getter,由于 phone 是 repeated 类型的,所以还多了通过 index 来获取和改变某一个元素的 setter 和 getter,phone 还有一个获取数量的phone_size 函数。

(3)写 message 程序定义

// writer.cc
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"// C++标准程序库中的所有标识符都被定义于一个名为std的namespace中
// 方便后面使用标识符时不需要再加std扩展名
using namespace std;// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {// 接收用户idcout << "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.
// argc是命令行参数输入个数,*argv[]是命令行输入命令字符串的指针
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;
}

编译 writer.cc:

g++ writer.cc addressbook.pb.cc -lprotobuf
// 第一个writer是编译输出的执行程序名,第二个writer.cc是源代码
g++ -o writer writer.cc addressbook.pb.cc -lprotobuf

(4)读 message 程序定义

// reader.cc
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;// 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.person_size(); i++) {const tutorial::Person& person = address_book.person(i);cout << "Person ID: " << person.id() << endl;cout << "  Name: " << person.name() << endl;if (person.has_email()) {if (person.has_email()) {cout << "  E-mail address: " << person.email() << endl;}for (int j = 0; j < person.phone_size(); j++) {const tutorial::Person::PhoneNumber& phone_number = person.phone(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;}cout << phone_number.number() << 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;
}

编译 reader.cc:

g++ -o reader reader.cc addressbook.pb.cc -lprotobuf

(4)测试

执行 writer 程序添加两个联系人:

// 查看用法
./writer
Usage:  ./writer ADDRESS_BOOK_FILE// 执行写
./writer MyAddressBook.bin
MyAddressBook.bin: File not found.  Creating a new file.
Enter person ID number: 101
Enter name: zyy
Enter email address (blank for none): zyy@hotmail.com
Enter a phone number (or leave blank to finish): 123456
Is this a mobile, home, or work phone? mobile
Enter a phone number (or leave blank to finish): 029123
Is this a mobile, home, or work phone? home
Enter a phone number (or leave blank to finish):
(base) zyy@supermicro:/data/zyy/usr/file$(base) zyy@supermicro:/data/zyy/usr/file$ ./writer MyAddressBook.bin
Enter person ID number: 123
Enter name: abc
Enter email address (blank for none): abc@hotmail.com
Enter a phone number (or leave blank to finish): 10086
Is this a mobile, home, or work phone? work
Enter a phone number (or leave blank to finish):
(base) zyy@supermicro:/data/zyy/usr/file$

执行 reader 程序读取刚添加的联系人:

// 查看用法
(base) zyy@supermicro:/data/zyy/usr/file$ ./reader
Usage:  ./reader ADDRESS_BOOK_FILE// 执行读
(base) zyy@supermicro:/data/zyy/usr/file$ ./reader MyAddressBook.bin
Person ID: 101Name: zyyE-mail address: zyy@hotmail.comMobile phone #: 123456Home phone #: 029123
Person ID: 123Name: abcE-mail address: abc@hotmail.comWork phone #: 10086

参考:
Caffe代码解析(2)
Protocol-Buffer-Beginner-Guide

Protobuf 学习(二)编译proto文件并测试相关推荐

  1. 【Protobuf速成指南】.proto文件的编写与编译

    文章目录 1.0版本 一.编写.proto文件 1.文件规范: 2.注释方式: 3.指定proto3语法: 4.package申明符 5.定义message 6.编写消息字段 ①类型对照表 ②唯一编号 ...

  2. 【Golang | gRPC】使用protoc编译.proto文件

    环境: Golang: go1.18.2 windows/amd64 protoc:libprotoc 3.21.1 1. 安装protoc 使用protoc编译.proto文件,首先需要正确安装pr ...

  3. AVI音视频封装格式学习(二)——AVI RIFF文件参考

    AVI RIFF文件参考 AVI RIFF File Reference 微软AVI文件格式是与捕获,编辑和播放音视频流的应用程序一起使用的RIFF文件规范.通常,AVI文件包含多个不同类型的数据流. ...

  4. IDEA插件GenProtobuf编译proto文件

    安装protoc protoc是proto编译器,从这里下载:https://github.com/protocolbuffers/protobuf/releases/ 我使用的是mac系统,安装方法 ...

  5. Caffe-windows入门学习,编译、训练、测试详细教程

    ####目录结构 一. 准备工作 二. 编译 2.1.开启相关caffe版本的编译开关配置内容 2.2.手动更改或者指定版本对应编译器目录 2.3.下载依赖文件dependencies文件到指定目录 ...

  6. Google Protobufs(1) - maven工程使用protoc插件编译proto文件

    maven 工程将proto文件编译成java文件 1.使用os-maven-plugin + protobuf-maven-plugin 使用os-maven-plugin插件,获取操作系统信息,之 ...

  7. Cocos Creator TypeScript 中使用ProtoBuf(利用工具把proto文件生成对应的js文件以及ts文件)

    我是一枚刚入坑cocos的小白o(╯□╰)o 开发环境:Cocos Creator 1.9   (需要安装Node.js,使用npm命令) 在网上找了很久都是讲的protobuf.js的用法,但是没有 ...

  8. 用protoc编译.proto文件遇到的问题

    报错:object_detection/protos/flexible_grid_anchor_generator.proto: File not found. object_detection/pr ...

  9. 编译proto文件python_Python:如何将proto文件编译为python文件

    说明: 最近刚刚开始接触接口的编写,用的是有关grpc远程调用.我还没太搞明白接口是怎么回事,但我的初步目标可以简单理解为生成两个python文件.比如你的proto文件名是ABC,那么我的目标是生成 ...

最新文章

  1. qt调用linux系统的线程函数吗,Qt之主线程与子线程通讯(linux下)
  2. Linux环境进程间通信(二): 信号--转载
  3. 018 jquery中的事件
  4. TCP三次握手及其背后的缺陷
  5. 超标量、超级流水线、超长指令字、向量机 SIMD
  6. Linux内核锁实现原理,linux 大内核锁原理
  7. 游戏服务器红点系统,Unity简易的红点系统RedPoint System
  8. python编程快速上手实践项目答案_python编程快速上手之第4章实践项目参考答案...
  9. python摄像头识别快递单号查询_python如何免费对接快递鸟api单号识别查询接口
  10. How to find error message from OMS repository
  11. Docker教程:dokcer的配置和命令
  12. 重写对象的equals和hashCode方法
  13. java伪代码生成器_java伪代码怎么写
  14. 网易服务器维护,网易:方便玩家 各大区服务器维护详细时间表列
  15. win10设置宽带拨号断线重连
  16. STC开天斧USB仿真
  17. 几何基础 罗德里格公式
  18. hive中NULL值问题
  19. 中职网络安全2021年国赛Wireshark流量分析题目解析
  20. HMI智能座舱自动化测试之性能测试

热门文章

  1. 物联网行业的发展的趋势、现状与挑战
  2. [S.C.1] 微服务基本知识
  3. android开发悬浮窗权限,Android 悬浮窗权限校验和
  4. 网站的背景音乐在服务器上不播放,急急急...博客背景音乐添加后不能播放?老是跳出无法与服务器连接? 爱问知识人...
  5. Spring循环依赖解决源码解析
  6. linux学习需要什么基础,学linux需要什么基础?
  7. 【Shell】编程之CASE语句+函数+正则(6)
  8. SpringBoot+mysql搭建微信小程序后台(4)服务器搭建
  9. 北京理工大学-操作系统原理 第2章作业2
  10. ios动画-新浪微博app点击发微博按钮动画的实现