我的例子是為了證明Protocol Buffer良好的跨語言特性。
例子由兩個程式構成,一個是C++程式,負責將對象User序列化到檔案中。另一個是Java程式,負責從檔案中還原序列化成User對象。
下面的圖形反映了兩個程式以及Protocol Buffer之間的關係。
先設計User對象的proto檔案,Protocol Buffer編譯器要利用它產生C++檔案和Java檔案。
package sample;option java_package = "org.freebird.sample";option java_outer_classname = "UserProto";message User { required string name = 1; required string email = 2;}
對於產生的C++檔案,User類 位於namespace sample中
對於產生的Java檔案, 編譯器建立了一個類 UserProto ,package名稱為 org.freebird.sample, UserProto 類有一個公有內部靜態類 User
假定sample.proto檔案位於template目錄,目錄下我建立了一個build.sh檔案:
rm -rf c++mkdir c++rm -rf javamkdir javaprotoc -I=./ --cpp_out=./c++ --java_out=./java ./sample.proto這個指令碼很簡單,每次執行都會建立c++和java目錄,並將產生的檔案放在這兩個目錄下。目錄結構如下:$ tree templatetemplate├── build.sh├── c++│ ├── sample.pb.cc│ └── sample.pb.h├── java│ └── org│ └── freebird│ └── sample│ └── UserProto.java└── sample.proto
現在來看看C++程式。建立CMake工程的目錄結構如下:
$ tree c++c++├── build├── CMakeLists.txt├── include└── src ├── CMakeLists.txt └── main.cpp
匯入需要的標頭檔,原始碼檔案和庫:
cmake_minimum_required(VERSION 2.8.7)set(CMAKE_BUILD_TYPE Debug)set(PROJECT_INCLUDE_DIR ../include)set(TEMPLATE_DIR ../../../template)include_directories(${TEMPLATE_DIR}/c++ ${PROJECT_INCLUDE_DIR})AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src CPP_LIST1)AUX_SOURCE_DIRECTORY(${TEMPLATE_DIR}/c++ CPP_LIST2)add_executable(sample ${CPP_LIST1} ${CPP_LIST2})target_link_libraries( sample protobuf)add_definitions(-Wall)編寫main.cpp的原始碼:
#include <iostream>#include <fstream>using namespace std;#include "sample.pb.h"using namespace sample;int main(int args,char* argv[]){ cout<<"welcome to the c++ sample for protocol buffer"<<endl; User user; user.set_name("freebird"); user.set_email("shu_chen@esri.com"); fstream output(argv[1], ios::out | ios::trunc | ios::binary); if (!user.SerializeToOstream(&output)) { cerr << "Failed to write user." << endl; return -1; } cout<<"Write to file: "<<argv[1]<<" successfully"<<endl;}運行程式:
$./sample ./awelcome to the c++ sample for protocol bufferWrite to file: ./a successfully
開啟結果檔案a
^Hfreebird^R^Qshu_chen@esri.com