(原)ubuntu16中简单的使用google的protobuf
转载请注明出处:
http://www.cnblogs.com/darkknightzh/p/5804395.html
参考网址:
http://www.cnblogs.com/luosongchao/p/3969988.html
1. 在当前文件夹内新建addressbook.proto,并输入:
package ContactInfo; message Person
{
required string curName = 1;
required int32 curId = 2;
optional string curEmail = 3; enum PhoneType
{
MOBILE = 0;
HOME = 1;
WORK = 2;
} message PhoneNumber
{
required string number = 4;
optional PhoneType type = 2[default = HOME];
} repeated PhoneNumber phone = 4;
} message AddressBook
{
required string owner = 10;
repeated Person personInfo = 6;
}
2. 将终端定位到当前文件夹,并输入:
protoc --cpp_out=./ addressbook.proto
说明:a 如果希望生成的.h和.cpp都在当前文件夹,则--cpp_out=./即可。
b 如果使用如下命令:
protoc -I=src --cpp_out=dst src/ addressbook.proto
则addressbook.proto在当前文件夹的src文件夹里,生成的.h和.cpp均位于当前文件夹下的dst文件夹下面。
c 生成的头文件中,ContactInfo为命名空间,里面包含Person、PhoneNumber、AddressBook三个类。枚举类型则看该类型所在的类,使用作用域限定符来访问,如:
ContactInfo::Person::MOBILE
3. 在生成的.h和.cpp文件所在的文件夹内,新建testAddBook.cpp,并输入:
#include "addressbook.pb.h"
#include <fstream>
#include <iostream>
using namespace std; /////////////////////////////////////////////////////////////////////////////////
int saveAddInfo()
{
ContactInfo::AddressBook addbook;
addbook.set_owner("xxx"); // first person
ContactInfo::Person* pperson = addbook.add_personinfo();
pperson->set_curname("aaa");
pperson->set_curid();
pperson->set_curemail("aaa@126.com"); ContactInfo::Person_PhoneNumber* pPhoneNum = pperson->add_phone();
pPhoneNum->set_number("");
pPhoneNum->set_type(ContactInfo::Person::HOME); pPhoneNum = pperson->add_phone();
pPhoneNum->set_number("");
pPhoneNum->set_type(ContactInfo::Person::MOBILE); // second person
pperson = addbook.add_personinfo();
pperson->set_curname("bbb");
pperson->set_curid();
// pperson->set_curemail("bbb@126.com"); pPhoneNum = pperson->add_phone();
pPhoneNum->set_number("");
// pPhoneNum->set_type(ContactInfo::Person::HOME); pPhoneNum = pperson->add_phone();
pPhoneNum->set_number("");
pPhoneNum->set_type(ContactInfo::Person::MOBILE); // int length = addbook.ByteSize();
// char* buf = new char[length]; // serialize to char*, and transmit by net or others
// addbook.SerializeToArray(buf,length); fstream output("pbinfo.log", ios::out|ios::trunc|ios::binary);
if(!addbook.SerializeToOstream(&output))
{
cerr << "fail to write msg" << endl;
//delete[] buf;
return -;
} //delete[] buf;
return ;
} ////////////////////////////////////////////////////////////////////////////
void showMsg(const ContactInfo::AddressBook& addbook)
{
cout << addbook.owner() << endl;
for (int i = ; i < addbook.personinfo_size(); ++i)
{
cout << addbook.personinfo(i).curname() << endl;
cout << addbook.personinfo(i).curid() << endl;
if(addbook.personinfo(i).has_curemail())
cout << addbook.personinfo(i).curemail() << endl;
else
cout << "no email" << endl; for (int j = ; j < addbook.personinfo(i).phone_size(); ++j)
{
cout<<addbook.personinfo(i).phone(j).number() << endl;
if(addbook.personinfo(i).phone(j).has_type())
cout << addbook.personinfo(i).phone(j).type() << endl;
else
cout << "no phone type" << endl;
}
}
} void showMsgbyAuto(ContactInfo::AddressBook addbook)
{
cout << addbook.owner() << endl; auto pperson = addbook.mutable_personinfo();
for (auto it = pperson->begin(); it != pperson->end(); ++it)
{
cout << it->curname() << endl;
cout << it->curid() << endl;
if(it->has_curemail())
cout << it->curemail() << endl;
else
cout << "no email" << endl; auto pPhoneNum = it->mutable_phone();
for (auto ij = pPhoneNum->begin(); ij != pPhoneNum->end(); ++ij)
{
cout << ij->number() << endl;
if(ij->has_type())
cout << ij->type() << endl;
else
cout << "no phone type" << endl;
}
}
} int loadAddInfo()
{
ContactInfo::AddressBook addbook; fstream input("pbinfo.log", ios::in|ios::binary);
if(!addbook.ParseFromIstream(&input))
{
cout << "fail to write msg" << endl;
return -;
}
cout << "now show msg" << endl;
showMsg(addbook);
cout << endl;
showMsgbyAuto(addbook); return ;
} ///////////////////////////////////////////////////////////////////////////////
int main()
{
int choice;
cout << "input choice: 1 for save, 2 for load" << endl;
cin >> choice;
if( == choice)
{
saveAddInfo();
}
else if ( == choice)
{
loadAddInfo();
} return ;
}
说明:上面程序使用SerializeToArray后,可以将数据放到buf的缓冲区中,方便使用网络或者其他方式发送。
4. 终端定位到testAddBook.cpp所在文件夹,并输入:
g++ -std=c++ addressbook.pb.cc testAddBook.cpp -o testAddBook -lprotobuf -pthread
说明:a 上面程序showMsgbyAuto函数使用了C++11特性,因而终端中需要加上-std=c++11;否则可以不加。如果不使用C++11特性,则使用下面的方式访问,但是太长。。。:
::google::protobuf::RepeatedPtrField< ::ContactInfo::Person >
b 如果protobuf没有安装到/usr路径,而是/usr/local路径,可能需要下面的命令:

c 此处不能使用gcc编译,我这里提示出错了:
/usr/bin/ld: /tmp/ccO3HeHo.o: undefined reference to symbol '_ZNSaIcED1Ev@@GLIBCXX_3.4'
//usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
===========================================================================
170122更新:
d 如果编译该cpp文件的时候,提示好多未定义的引用:
addressbook.pb.cc:(.text+0x133):对‘google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(google::protobuf::Descriptor const*, google::protobuf::Message const*, int const*, int, int, int, int, int, int)’未定义的引用
addressbook.pb.cc:(.text+0x193):对‘google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(google::protobuf::Descriptor const*, google::protobuf::Message const*, int const*, int, int, int, int, int, int)’未定义的引用
可能是因为电脑安装了两个不同版本的protobuf(ubuntu16默认已经安装了protobuf.so.9这系列的,新装的是protobuf.so.10系列的)。默认的路径见http://www.cnblogs.com/darkknightzh/p/5782992.html中160819更新。
170122更新结束
===========================================================================
5. 终端中输入./testAddBook,之后输入1,会存储pbinfo.log文件。
6. 终端中输入./testAddBook,之后输入2,显示如下:

说明解析的文件成功。
说明:对于optional可选项,可以不使用has_xxx()进行判断,此时不输出(程序有endl,所以会输出一个空行)(不知道其他使用方式时,会是什么情况)。
(原)ubuntu16中简单的使用google的protobuf的更多相关文章
- (原)Ubuntu16中卸载并重新安装google的Protocol Buffers
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5782992.html 目前最新的是1.6.1 1. 卸载掉老版本的Protocol: sudo apt ...
- [软件测试]Linux环境中简单清爽的Google Test (GTest)测试环境搭建(初级使用)
本文将介绍单元测试工具google test(GTEST)在linux操作系统中测试环境的搭建方法.本文属于google test使用的基础教程.在linux中使用google test之前,需要对如 ...
- (原)ubuntu16中安装moses
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5653186.html 在ubuntu14中,可以使用下面的语句安装moses: luarocks in ...
- 在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程)
在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程) 原文链接:http://www.360doc.com/content/14/1117/10/16948208_42571794 ...
- Java原子类中CAS的底层实现
Java原子类中CAS的底层实现 从Java到c++到汇编, 深入讲解cas的底层原理. 介绍原理前, 先来一个Demo 以AtomicBoolean类为例.先来一个调用cas的demo. 主线程在f ...
- google的protobuf简单介绍
google的protobuf是一种轻便高效的结构化数据存储格式,在通信协议和数据存储等领域中使用比较多.protobuf对于结构中的每个成员,会提供set系列函数和get系列函数. 但是,对于使用来 ...
- Unity3D中简单的C#异步Socket实现
Unity3D中简单的C#异步Socket实现 简单的异步Socket实现..net框架自身提供了很完善的Socket底层.笔者在做Unity3D小东西的时候需要使用到Socket网络通信.于是决定自 ...
- 神奇的 SQL 之层级 → 为什么 GROUP BY 之后不能直接引用原表中的列
前言 开心一刻 感觉不妙呀,弟弟舔它! 不该舔的,舔到怀疑人生了...... GROUP BY 后 SELECT 列的限制 标准 SQL 规定,在对表进行聚合查询的时候,只能在 SELECT 子句中写 ...
- [转]神奇的 SQL 之层级 → 为什么 GROUP BY 之后不能直接引用原表中的列
原文:https://www.cnblogs.com/youzhibing/p/11516154.html 这篇文章,对group by的讲解不错 -------------------------- ...
随机推荐
- android布局常用属性记录
android布局常用属性记录 http://blog.csdn.net/xn4545945/article/details/7717086这里有一部分别人总结的其余的: align:对齐 par ...
- 从运行原理及使用场景看Apache和Nginx
用正确的工具,做正确的事情. 本文只作为了解Apache和Nginx知识的一个梳理,想详细了解的请阅读文末参考链接中的博文. Web服务器 Web服务器也称为WWW(WORLD WIDE WEB)服务 ...
- 更快的方式实现PHP数组去重(转)
概述 使用PHP的array_unique()函数允许你传递一个数组,然后移除重复的值,返回一个拥有唯一值的数组.这个函数大多数情况下都能工作得很好.但是,如果你尝试在一个大的数组里使用array_u ...
- UVA1589 Xiangqi
Xiangqi is one of the most popular two-player board games in China. The game represents a battle bet ...
- 正则匹配<img src="xxxxxx" alt="" />标签的相关写法
1.(<img\ssrc[^>]*>) 2.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*&g ...
- Blogger建立新文章 - Blog透视镜
使用Blogger,建立好Blog部落格之后,接着就是建立新文章,它是Blog部落格的灵魂,先从简单开始,来了解建立新文章的标题,文章中如何上传图片,建立卷标,及设定排程日期,定时自动发布等这些功能, ...
- (摘) MDI登陆问题
MDI编程中需要验证用户身份,那么登陆窗口就需要在验证密码后进行相关的隐藏处理. (1)隐藏登陆窗口(登陆窗体作为启动) 登陆按钮事件:this.Hide();//隐藏登陆窗口MDI_Name M = ...
- VIJOS 1052贾老二算算术 (高斯消元)
描述 贾老二是个品学兼优的好学生,但由于智商问题,算术学得不是很好,尤其是在解方程这个方面.虽然他解决 2x=2 这样的方程游刃有余,但是对于 {x+y=3 x-y=1} 这样的方程组就束手无策了.于 ...
- 深入浅出Node.js (5) - 内存控制
5.1 V8的垃圾回收机制与内存限制 5.1.1 Node与V8 5.1.2 V8的内存限制 5.1.3 V8的对象分配 5.1.4 V8的垃圾回收机制 5.1.5 查看垃圾回收日志 5.2 高效使用 ...
- WPF的数据绑定详细介绍
数据绑定:是应用程序 UI 与业务逻辑之间建立连接的过程. 如果绑定正确设置并且数据提供正确通知,则当数据的值发生更改时,绑定到数据的视觉元素会自动反映更改. 数据绑定可能还意味着如果视觉元素中数据的 ...