在VC++中使用ProtoBuf,
1,新建一个文本文件,另存文件名为person.proto, 在文件中定义Proto消息,如下:
syntax = "proto3"; package myPbMsg; message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { optional string number = 1; optional PhoneType type = 2; } repeated PhoneNumber phone = 4; }
2,用Protoc.exe编译Proto消息(在准备工作中,已经获得protoc.exe),可将如下代码保存为comp_person.bat,执行此批处理文件即可编译person.proto。
person.proto, com_person.bat 需拷贝至protoc.exe相同的文件夹,编译后生成person.pb.h, person.pb.cc两个C++文件
echo "以下命令,会编译person.proto,生成c++的文件" protoc.exe --cpp_out=. person.proto pause
3,新建VC++控制台项目,将上述步骤2生成的c++文件复制到VC项目源代码路径下,并将这两个文件加入项目中:person.pb.h, person.pb.cc;
此外,需将ProtoBuf源代码中的google文件夹复制到VC++项目文件夹路径之下, 将google文件夹路径加入VC++项目的输入路径;
还需将libprotobuf.lib包含进VC项目(项目属性->链接器->输入:(Debug)添加 libprotobufd.lib; (Release)添加 libprotobuf.lib)。
4, person.pb.h文件中需手动添加一个预定义宏,以解决编译时提示的一个链接错误,如下:
#define PROTOBUF_USE_DLLS
5,ProtoBuf序列化和反序列化操作,例子如下:
#include "stdafx.h" #include <fstream> #include "person.pb.h" using namespace std; using namespace myPbMsg; //Person序列化 void person_serialize() { Person person; person.set_name("Mike Jordon"); person.set_id(1001); person.set_email("[email protected]"); Person_PhoneNumber *pPhone = person.add_phone(); pPhone->set_type(Person_PhoneType::Person_PhoneType_MOBILE); pPhone->set_number("13800138000"); fstream output("myfile.serial", ios::out | ios::binary); person.SerializeToOstream(&output); } //Person反序列化 void person_unSerialize() { fstream input("myfile.serial", ios::in | ios::binary); Person person; person.ParseFromIstream(&input); cout << "ID: " << person.id() << endl; cout << "Name: " << person.name() << endl; cout << "E-mail: " << person.email() << endl; if(person.phone().size()) cout << "Phone: " << person.phone().at(0).number() << endl; } int main() { person_serialize(); person_unSerialize(); system("pause"); return 0; }
6,编译VC++工程,libprotobuf.dll文件复制到VC输出文件夹,执行VC生成的文件即可,VS2015的VC++编译时可能遇到一些错误提示,根据提示,在项目属性中添加如下预定义宏解决:
_SCL_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
测试例子输出结果如下: