转载请注明出处:

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. jquery简单的拖动效果

    <!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/h ...

  2. js页面加载进度条(这个就比较正式了,改改时间就完事儿)

    不废话,直接上代码 思路不难,就是一个animate方法配合随机数 duration内个三秒钟,是自定义的,可以改成页面加载时间,这样就完美了 <!doctype html> <ht ...

  3. php 简单分页

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. ffmpeg编译时freetype2 not found错误

    自己安装的libfreetype2在/usr/local/lib目录下export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

  5. Angular2 和TypeScript

    Angular2 和TypeScript 原文链接:https://www.infoq.com/articles/Angular2-TypeScript-High-Level-Overview 作者: ...

  6. Unity3D 定时发射子弹

    using UnityEngine; public class example : MonoBehaviour { public GameObject projectilePrefab; public ...

  7. hdu 4578 Transformation

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 题意:1,a,b,c代表在a,b区间的每一个数加上c:2,a,b,c代表在a,b区间的每一个数乘上c: 3 ...

  8. Factorials 阶乘

    Description N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例 ...

  9. UVA1218--树形DP

    没有看书和题解做的一道树形DP题,思路很清晰..只是debug上花了很久的时间才发现看错了条件..并不是每个点都只能和一台服务器相邻,而是非服务器的点只能和一台服务器相邻..看错了一个条件差距大了去了 ...

  10. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅲ

    2.4.3 堆的定义 数据结构二叉堆能够很好地实现优先队列的基本操作.在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素.相应地,这些位置的元素又至少要大于等于数组中的两个元素,以此类推. ...