在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
測試例子輸出結果如下: