前言:
Protobuf做爲數據交換格式, 被不少人喜歡. 數據壓縮比高, 向後兼容性強, 性能優異, 並且對平臺中性, 支持多語言(C/C++, JAVA, Python). 優勢太多, 實在不勝枚舉(居家旅行, 殺人放火必備良藥, oh yeah! ^_^).
本篇文章着重記錄Linux下對C/C++版Protobuf的編譯/連接和API使用.c++
Protobuf下載和安裝
讓咱們使用protobuf 2.4.1做爲樣例來展現.
社區url: http://code.google.com/p/protobuf/
下載連接: http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
如下是相關的命令和操做
1). 下載和解壓
wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz
tar -jxvf protobuf-2.4.1.tar.gz
2). 編譯和安裝
./configure --disable-shared --prefix=/path/to
make && make install
3). 目錄結構
tree -L 2 # 兩層的目錄結構(bin/inculde/lib), 以下所示:
評註: bin/protoc 是pb生成工具, include, lib則是對應的頭文件和相應的靜態/動態庫app
實戰演示
讓咱們來編輯一下msg.proto文件工具
message msg_t { required int32 id = 1; }
評註: 簡單定義了msg_t類
藉助protoc來生成相應語言版本的序列/反序列代碼性能
protoc --cpp_out=./ msg.proto
評註: --cpp_out指定了c/c++版本代碼的輸出路徑
最終生成 msg.pb.cc msg.pb.h 兩文件
編寫以下測試代碼:測試
#include "msg.pb.h" #include <stdio.h> #include <assert.h> int main() { char buf[1024] = {'\0'}; int buf_len = 0; msg_t msg1; msg1.set_id(1001); // *) serialize phrase => object to byte array msg1.SerializeToArray(buf, sizeof(buf)); buf_len = msg1.ByteSize(); msg_t msg2; // *) deserialize phrase => byte array to object msg2.ParseFromArray(buf, buf_len); assert(msg1.id() == msg2.id()); return 0; }
進行編譯並運行
g++ -o app app.cpp msg.pb.cc -I/path/to/protobuf/include -L/path/to/protobuf/lib -lprotobuf -lpthread
./app
評註: /path/to爲具體protobuf的安裝目錄 ui
連接方式
靜態連接仍是動態連接? 這是個問題!
在指定的protobuf庫路徑中, 若是存在動態鏈接庫, 則編譯的程序優先選擇動態連接, 不然則採用靜態連接的方式.
讓咱們用圖來對比說明
動態連接方式
在protobuf的lib目錄中, 若存在動態鏈接庫(so文件)
則編譯後的app可執行程序
使用ldd app分析, 存在以下依賴項
評註: 紅線區域標明瞭引用了動態鏈接庫libprotobuf.so.7
直接執行二進制app文件, 遇到以下錯誤google
./app: error while loading shared libraries: libprotobuf.so.7: cannot open shared object file: No such file or directory
顯然這邊須要設定LD_LIBRARY_PATH變量url
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/path/to/protobuf/lib
評註: /path/to/protobuf/lib爲實際的protobuf安裝路徑
靜態連接方式
簡單的在lib目錄移除全部動態鏈接庫(so)文件,
而後進行編譯, 使用ldd分析
直接執行app就能夠了code
總結:
這邊主要講述了protobuf的編譯/安裝, 以及小demo編寫, 重要的講述了靜態連接和動態連接的區別. 網上資料多以動態連接居多, 但實際上靜態連接的方式的須要更直接些.blog