转载请注明出处:

http://www.cnblogs.com/darkknightzh/p/5804395.html

参考网址:

http://www.cnblogs.com/luosongchao/p/3969988.html

http://www.codeweblog.com/protocol-buffer%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8-%E9%9D%9E%E5%B8%B8%E8%AF%A6%E7%BB%86/

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.html160819更新

170122更新结束

===========================================================================

5. 终端中输入./testAddBook,之后输入1,会存储pbinfo.log文件。

6. 终端中输入./testAddBook,之后输入2,显示如下:

说明解析的文件成功。

说明:对于optional可选项,可以不使用has_xxx()进行判断,此时不输出(程序有endl,所以会输出一个空行)(不知道其他使用方式时,会是什么情况)。

(原)ubuntu16中简单的使用google的protobuf的更多相关文章

  1. (原)Ubuntu16中卸载并重新安装google的Protocol Buffers

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5782992.html 目前最新的是1.6.1 1. 卸载掉老版本的Protocol: sudo apt ...

  2. [软件测试]Linux环境中简单清爽的Google Test (GTest)测试环境搭建(初级使用)

    本文将介绍单元测试工具google test(GTEST)在linux操作系统中测试环境的搭建方法.本文属于google test使用的基础教程.在linux中使用google test之前,需要对如 ...

  3. (原)ubuntu16中安装moses

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5653186.html 在ubuntu14中,可以使用下面的语句安装moses: luarocks in ...

  4. 在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程)

    在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程) 原文链接:http://www.360doc.com/content/14/1117/10/16948208_42571794 ...

  5. Java原子类中CAS的底层实现

    Java原子类中CAS的底层实现 从Java到c++到汇编, 深入讲解cas的底层原理. 介绍原理前, 先来一个Demo 以AtomicBoolean类为例.先来一个调用cas的demo. 主线程在f ...

  6. google的protobuf简单介绍

    google的protobuf是一种轻便高效的结构化数据存储格式,在通信协议和数据存储等领域中使用比较多.protobuf对于结构中的每个成员,会提供set系列函数和get系列函数. 但是,对于使用来 ...

  7. Unity3D中简单的C#异步Socket实现

    Unity3D中简单的C#异步Socket实现 简单的异步Socket实现..net框架自身提供了很完善的Socket底层.笔者在做Unity3D小东西的时候需要使用到Socket网络通信.于是决定自 ...

  8. 神奇的 SQL 之层级 → 为什么 GROUP BY 之后不能直接引用原表中的列

    前言 开心一刻 感觉不妙呀,弟弟舔它! 不该舔的,舔到怀疑人生了...... GROUP BY 后 SELECT 列的限制 标准 SQL 规定,在对表进行聚合查询的时候,只能在 SELECT 子句中写 ...

  9. [转]神奇的 SQL 之层级 → 为什么 GROUP BY 之后不能直接引用原表中的列

    原文:https://www.cnblogs.com/youzhibing/p/11516154.html 这篇文章,对group by的讲解不错 -------------------------- ...

随机推荐

  1. Reverse digits of an integer.

    class Solution { public: int reverse(int x) { ;//long 是怕中间过程溢出 <<,max=-min-){ ans=ans*+x%; x=x ...

  2. 移动端Web开发笔记

    最近写的一个移动端项目:上海 地铁指路通,之间遇到的一些问题,记录下来(以后会不断补充的): 1. 丰富的页面Meta: 1.1: 控制显示区域各种属性: <meta content=" ...

  3. [OpenJudge] 百练2754 八皇后

    八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. ...

  4. 自定义Filter服务

    自定义一个用户Email长度超过12个字符后值截取前12个然后添加“...”显示. 例如: index.html <!DOCTYPE html> <html ng-app=" ...

  5. windows phone之获取当前连接WIFI的SSID

    public string GetSSIDName() { foreach (var network in new NetworkInterfaceList()) { if ( (network.In ...

  6. 选择排序(Selection Sort)

    选择排序就是在选择数组元素上做文章,关键是如何选择?选择的标准是什么?选择之后放在哪?所有这些都是选择排序的问题. 选择排序算法中,通常会有以下操作: 从数组第一个元素开始. 遍历整个数组,找到最小的 ...

  7. 一个跨域请求的XSS漏洞

    场景回顾 一个表单进行跨域提交的方式有很多,我们使用的采用隐藏iframe,在本域下放一个代理页面,通过服务端配合完成一次完整的请求. 首先,部署proxy.html代理页面.这个页面处理服务端返回的 ...

  8. hdu 3853 LOOPS(概率 dp 期望)

    Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help ...

  9. URL重写是实现PHP伪静态

    URL重写是实现PHP伪静态 应该这样说才是,URL重写是实现PHP伪静态的方式之一, 具体如: http://www.plframe.com/?x=1&y=2&z=3 换成 http ...

  10. hadoop执行hbase插入表操作,出错:Stack trace: ExitCodeException exitCode=1:(xjl456852原创)

    在执行hbase和mapreduce融合时,将hdfs上的文本文件插入到hbase中,我没有使用"胖包"(胖包就是将项目依赖的jar包放入项目打包后的lib目录中),而是直接将hb ...