1、linux上安装protobuf3:
1)下载:
https://download.csdn.net/download/liuxiao723846/11584862
2)编译安装:
function check_install_status() {
if [ $? -ne 0 ]; then
echo "--!!ERROR"
exit 1
fi
}
#install protobuf3
if [ ! -d protobuf-3.6.0 ]; then
tar -zxf protobuf-3.6.0.tar.gz
cd protobuf-3.6.0
./autogen.sh
./autogen.sh && ./configure
check_install_status
make -j8
check_install_status
make install
check_install_status
cd python
python setup.py install
check_install_status
ldconfig
cd ../../
fi
2、简单示例:
1)person.proto:
package test;
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
}
编译,生成C++代码:
$ protoc ./person.proto --cpp_out=./
$ ll
-rw-rw-r--. 1 roo roo 17237 Aug 20 21:19 person.pb.cc
-rw-rw-r--. 1 roo roo 12965 Aug 20 21:19 person.pb.h
2)编写C++业务代码:
#include
#include
#include "person.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/text_format.h"
using namespace test;
int main(){
Person p;
p.set_name("test");
p.set_id(1);
p.set_email("a.iabc.com");
//------------------将pb二进制信息保存到字符串
std::string str;
p.SerializeToString(&str);
std::cout<
3)编译、运行:
g++ -g -o run person_test.cpp ./person.pb.cc -I. -lprotobuf -pthread -std=c++11
或者
g++ -g -o run person_test.cpp ./person.pb.cc -I. -I/usr/local/protobuf/include -L/usr/local/protobuf/lib -lprotobuf -pthread -std=c++11
4)api说明:
3、复杂示例:
1)pb消息结构test.proto:
syntax = "proto2";
package video_stream;
message Item{
optional string id = 1;
optional float score = 2;
}
message ModelItems{
optional string modelName = 1;
repeated Item itemList = 2;
}
message ModelRecallInfoList{
repeated ModelItems modelItemsList = 1;
}
message InnerUserPrefResponse {
optional map user_feed_map = 1;
}
编译:
$ protoc ./test.proto --cpp_out=./
$ ll
-rw-rw-r--. 1 roo roo 55676 Aug 20 23:28 test.pb.cc
-rw-rw-r--. 1 roo roo 32236 Aug 20 23:28 test.pb.h
2)c++业务代码:
#include
#include
#include "test.pb.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/text_format.h"
using namespace video_stream;
int main(){
ModelRecallInfoList mrlist;
ModelItems* items;
Item* item;
//model_item1
items = mrlist.add_modelitemslist();
items->set_modelname("model_items1");
//item1
item = items->add_itemlist();
item->set_id("item1");
item->set_score(0.9);
//item2
item = items->add_itemlist();
item->set_id("item2");
item->set_score(1.2);
//model_items2
items = mrlist.add_modelitemslist();
items->set_modelname("model_items2");
//item1
item = items->add_itemlist();
item->set_id("model_item2_item1");
item->set_score(99.9);
std::string str;
mrlist.SerializeToString(&str);
//std::cout<
编译、运行:
g++ -g -o run test_main.cpp ./test.pb.cc -I. -lprotobuf -pthread -std=c++11
3)api说明:
pb对象中,子对象需要使用指针;
对于repeated类型:
pb对象.add_属性名() 添加一个子对象的指针;
pb对象.属性名_size()返回repeated大小;
pb对象.属性名(i)遍历其中一个子对象;
4、复杂消息示例2:
1)student.proto
package test;
message Address {
optional string name = 1;
optional string code = 2;
}
message Student {
required string name = 1;
required int32 id = 2;
repeated string email = 3;
optional Address ads = 4;
map other = 5;
}
编译
$ protoc ./student.proto --cpp_out=./
$ ll
-rw-rw-r--. 1 roo roo 55676 Aug 20 23:28 student.pb.cc
-rw-rw-r--. 1 roo roo 32236 Aug 20 23:28 student.pb.h
2)C++业务代码student_test.cpp:
#include
#include "student.pb.h"
#include "google/protobuf/text_format.h"
using namespace test;
int main(){
Student p;
p.set_name("test");
p.set_id(1);
p.add_email("a.yxz.com");
p.add_email("b.abc.com");
std::string* e = p.add_email();
*e = "c.iop.com";
Address* ads = p.mutable_ads();
ads->set_name("taiyuan");
ads->set_code("0351");
auto* map = p.mutable_other();
(*map)["biye"] = "nuc";
(*map)["job"] = "abc";
//============序列化成二进制
std::string str;
p.SerializeToString(&str);
//std::cout< o = p1.other();
google::protobuf::Map::iterator ite;
std::string others;
for(ite=o.begin();ite!=o.end();ite++){
others+=ite->first+":"+ite->second;
}
std::cout<<"name:"<
3)说明:
补充:对于map的操作:
::google::protobuf::Map< ::std::string, ::std::string >* map = test.mutable_values();
cout << "size: " << f.values_size() << endl; // size = 0
// add to map
(*map)["a"] = "a1";
(*map)["c"] = "a1";
(*map)["a"] = "a1";
cout << "size: " << f.values_size() << endl; // size = 3
也可以使用下面:
auto& map = *test.mutable_values();
map["a"] = "a1";
参考:
https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#map-fields
https://www.cnblogs.com/shine-lee/p/10701810.html
http://xcd.blog.techweb.com.cn/archives/173.html
https://www.cnblogs.com/tangxin-blog/p/8314563.html