[轉]google protobuf安裝與使用
google protobuf是一個靈活的、高效的用於序列化資料的協議。相比較XML和JSON格式,protobuf更小、更快、更便捷。google protobuf是跨語言的,並且自帶了一個編譯器(protoc),只需要用它進行編譯,可以編譯成Java、python、C++、C#、Go等程式碼,然後就可以直接使用,不需要再寫其他程式碼,自帶有解析的程式碼。更詳細的介紹見: Protocol Buffers
protobuf安裝
1、下載protobuf程式碼 google/protobuf
2、安裝protobuf
tar -xvf protobuf
cd protobuf
./configure --prefix=/usr/local/protobuf
make
make check
make install
至此安裝完成^_^,下面是配置:
(1) vim /etc/profile,新增
export PATH=$PATH:/usr/local/protobuf/bin/
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
儲存執行,source /etc/profile。同時在~/.profile中新增上面兩行程式碼,否則會出現登入使用者找不到protoc命令。
(2) 配置動態連結庫
vim /etc/ld.so.conf,在檔案中新增/usr/local/protobuf/lib(注意: 在新行處新增),然後執行命令: ldconfig
.proto檔案
.proto檔案是protobuf一個重要的檔案,它定義了需要序列化資料的結構。使用protobuf的3個步驟是:
1 在.proto檔案中定義訊息格式
2 用protobuf編譯器編譯.proto檔案
3 用C++/Java等對應的protobuf API來寫或者讀訊息
程式示例(C++版)
該程式示例的大致功能是,定義一個Persion結構體和存放Persion的AddressBook,然後一個寫程式向一個檔案寫入該結構體資訊,另一個程式從檔案中讀出該資訊並列印到輸出中。
1 addressbook.proto檔案
package tutorial;
message Persion {
required string name = 1;
required int32 age = 2;
}
message AddressBook {
repeated Persion persion = 1;
}
編譯.proto檔案,執行命令: protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto,
示例中執行命令protoc --cpp_out=/tmp addressbook.proto ,會在/tmp中生成檔案addressbook.pb.h和addressbook.pb.cc。
2 write.cpp檔案,向檔案中寫入AddressBook資訊,該檔案是二進位制的
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 #include "addressbook.pb.h"
5
6 using namespace std;
7
8 void PromptForAddress(tutorial::Persion *persion) {
9 cout << "Enter persion name:" << endl;
10 string name;
11 cin >> name;
12 persion->set_name(name);
13
14 int age;
15 cin >> age;
16 persion->set_age(age);
17 }
18
19 int main(int argc, char **argv) {
20 //GOOGLE_PROTOBUF_VERIFY_VERSION;
21
22 if (argc != 2) {
23 cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
24 return -1;
25 }
26
27 tutorial::AddressBook address_book;
28
29 {
30 fstream input(argv[1], ios::in | ios::binary);
31 if (!input) {
32 cout << argv[1] << ": File not found. Creating a new file." << endl;
33 }
34 else if (!address_book.ParseFromIstream(&input)) {
35 cerr << "Filed to parse address book." << endl;
36 return -1;
37 }
38 }
39
40 // Add an address
41 PromptForAddress(address_book.add_persion());
42
43 {
44 fstream output(argv[1], ios::out | ios::trunc | ios::binary);
45 if (!address_book.SerializeToOstream(&output)) {
46 cerr << "Failed to write address book." << endl;
47 return -1;
48 }
49 }
50
51 // Optional: Delete all global objects allocated by libprotobuf.
52 //google::protobuf::ShutdownProtobufLibrary();
53
54 return 0;
55 }
編譯write.cpp檔案,g++ addressbook.pb.cc write.cpp -o write `pkg-config --cflags --libs protobuf` (注意,這裡的`符號在鍵盤數字1鍵左邊,也就是和~是同一個按鍵)。
3 read.cpp檔案,從檔案中讀出AddressBook資訊並列印
1 #include <iostream>
2 #include <fstream>
3 #include <string>
4 #include "addressbook.pb.h"
5
6 using namespace std;
7
8 void ListPeople(const tutorial::AddressBook& address_book) {
9 for (int i = 0; i < address_book.persion_size(); i++) {
10 const tutorial::Persion& persion = address_book.persion(i);
11
12 cout << persion.name() << " " << persion.age() << endl;
13 }
14 }
15
16 int main(int argc, char **argv) {
17 //GOOGLE_PROTOBUF_VERIFY_VERSION;
18
19 if (argc != 2) {
20 cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;
21 return -1;
22 }
23
24 tutorial::AddressBook address_book;
25
26 {
27 fstream input(argv[1], ios::in | ios::binary);
28 if (!address_book.ParseFromIstream(&input)) {
29 cerr << "Filed to parse address book." << endl;
30 return -1;
31 }
32 input.close();
33 }
34
35 ListPeople(address_book);
36
37 // Optional: Delete all global objects allocated by libprotobuf.
38 //google::protobuf::ShutdownProtobufLibrary();
39
40 return 0;
41 }
編譯read.cpp檔案,g++ addressbook.pb.cc read.cpp -o read `pkg-config --cflags --libs protobuf`
4 執行程式