Protobuf C/C++實戰筆記(1)


 

前言:
  Protobuf作為數據交換格式, 被很多人喜歡. 數據壓縮比高, 向后兼容性強, 性能優異, 而且對平台中性, 支持多語言(C/C++, JAVA, Python). 優點太多, 實在不勝枚舉(居家旅行, 殺人放火必備良葯, oh yeah! ^_^).
  本篇文章着重記錄Linux下對C/C++版Protobuf的編譯/鏈接和API使用.

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則是對應的頭文件和相應的靜態/動態庫

實戰演示
  讓我們來編輯一下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的安裝目錄 

鏈接方式
  靜態鏈接還是動態鏈接? 這是個問題!
  在指定的protobuf庫路徑中, 如果存在動態連接庫, 則編譯的程序優先選擇動態鏈接, 否則則采用靜態鏈接的方式.
  讓我們用圖來對比說明
  動態鏈接方式
  在protobuf的lib目錄中, 若存在動態連接庫(so文件)
  
  則編譯后的app可執行程序
  使用ldd app分析, 存在如下依賴項
  
  評注: 紅線區域標明了引用了動態連接庫libprotobuf.so.7
  直接執行二進制app文件, 遇到如下錯誤

./app: error while loading shared libraries: libprotobuf.so.7: cannot open shared object file: No such file or directory

  顯然這邊需要設定LD_LIBRARY_PATH變量

export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/path/to/protobuf/lib

  評注: /path/to/protobuf/lib為實際的protobuf安裝路徑
  靜態鏈接方式
  簡單的在lib目錄移除所有動態連接庫(so)文件,
  
  然后進行編譯, 使用ldd分析
  
  直接執行app就可以了

總結:
  這邊主要講述了protobuf的編譯/安裝, 以及小demo編寫, 重要的講述了靜態鏈接和動態鏈接的區別. 網上資料多以動態鏈接居多, 但實際上靜態鏈接的方式的需要更直接些.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM