转载请注明出处:

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. 【6】Laravel5.1的migration数据库迁移

    查看Laravel5.1的目录 当你配置好数据库后,在命令行执行下边的操作 php artisan migrate 打开数据库会发现,我们的数据库多了四个表,神奇吧! 打开任意一个migration查 ...

  2. React java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.edaixi.activity/lib-main/libgnustl_shared.so" is 32-bit instead of 64-bit

    E/AndroidRuntime: FATAL EXCEPTION: main Process: com.edaixi.activity, PID: 3659 at java.lang.Runtime ...

  3. CSS优先级、引入方式、Hack

    优先级 important > 内联(1,0,0,0) > id(1,0,0) > class(1,0) > element(1) > *通配符 css引入方式 方式一: ...

  4. destoon实现商铺管理主页设置增加新菜单的方法

    1.打开/lang/zh-cn/home.inc.php,找到9,10行替换如下: $HMENU = $DMENU = array('公司介绍', '供应产品', '采购清单', '新闻中心', '荣 ...

  5. 最短路--hdu2544

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  6. 自定义textView的高度

    原文地址: http://www.cocoachina.com/ios/20141226/10778.html iOS 8 之后的新特性

  7. 《Programming WPF》翻译 第5章 7.控件模板

    原文:<Programming WPF>翻译 第5章 7.控件模板 如果仔细的看我们当前的TTT游戏,会发现Button对象并没有完全为我们工作.哪些TTT面板有内圆角? 图5-14 这里 ...

  8. Thread详解

    具体可参考:Java并发编程:Thread类的使用,这里对线程状态的转换及主要函数做一下补充. 一.线程状态转换图 注意: 阻塞状态是线程阻塞在synchronized代码块时的状态,而阻塞在Lock ...

  9. 多目录下多文件 makefile编写

    前面已经分享了单目录项下多文件的makefile的编写,现在来看看多目录下多文件makefile的编写: 在做项目时,一般文件都会分几个目录来存放:基本的是  include/  bin/ src/ ...

  10. C++ builder 生成以管理员身份运行的exe

    转自:http://bbs.csdn.net/topics/310225109#post-312177603 ,稍微做了一点修改 创建一个文本文件,命名为123.manifest,内容如下: < ...