當前位置:
首頁 > 知識 > google gflags 庫完全使用

google gflags 庫完全使用

簡單介紹

gflags 是 google 開源的用於處理命令行參數的項目。

安裝編譯

項目主頁:gflags

? ~ git clone https://github.com/gflags/gflags.git # 下載源碼

? ~ cd gflags

? gflags git:(master) ? mkdir build && cd build # 建立文件夾

? build git:(master) ? cmake .. # 使用 cmake 編譯生成 Makefile 文件

? build git:(master) ? make # make 編譯

? build git:(master) ? sudo make install # 安裝庫

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這時 gflags 庫會默認安裝在 /usr/local/lib/ 下,頭文件放在 /usr/local/include/gflags/ 中。

基礎使用

我們從一個簡單的需求來看 gflags 的使用,只要一分鐘。假如我們有個程序,需要知道伺服器的 ip 和埠,我們在程序中有默認的指定參數,同時希望可以通過命令行來指定不同的值。

實現如下:

#include <iostream>

#include <gflags/gflags.h>

/**

* 定義命令行參數變數

* 默認的主機地址為 127.0.0.1,變數解釋為 "the server host"

* 默認的埠為 12306,變數解釋為 "the server port"

*/

DEFINE_string(host, "127.0.0.1", "the server host");

DEFINE_int32(port, 12306, "the server port");

int main(int argc, char** argv) {

// 解析命令行參數,一般都放在 main 函數中開始位置

gflags::ParseCommandLineFlags(&argc, &argv, true);

// 訪問參數變數,加上 FLAGS_

std::cout << "The server host is: " << FLAGS_host

<< ", the server port is: " << FLAGS_port << std::endl;

return 0;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

OK, 寫完了讓我們編譯運行。

? test g++ gflags_test.cc -o gflags_test -lgflags -lpthread # -l 鏈接庫進行編譯

? test ./gflags_test #不帶任何參數

The server host is: 127.0.0.1, the server port is: 12306

? test ./gflags_test -host 10.123.78.90 #只帶 host 參數

The server host is: 10.123.78.90, the server port is: 12306

? test ./gflags_test -port 8008 # 只帶 port 參數

The server host is: 127.0.0.1, the server port is: 8008

? test ./gflags_test -host 10.123.78.90 -port 8008 # host 和 port 參數

The server host is: 10.123.78.90, the server port is: 8008

? test ./gflags_test --host 10.123.78.90 --port 8008 # 用 -- 指定

The server host is: 10.123.78.90, the server port is: 8008

? test ./gflags_test --host=10.123.78.90 --port=8008 # 用 = 連接參數值

The server host is: 10.123.78.90, the server port is: 8008

? test ./gflags_test --help # 用 help 查看可指定的參數及參數說明

gflags_test: Warning: SetUsageMessage() never called

Flags from /home/rookie/code/gflags/src/gflags.cc:

.... # 略

Flags from /home/rookie/code/gflags/src/gflags_reporting.cc:

..... # 略

Flags from gflags_test.cc: #這裡是我們定義的參數說明和默認值

-host (the server host) type: string default: "127.0.0.1"

-port (the server port) type: int32 default: 12306

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

看,我們不僅快速完成了需求,而且似乎多了很多看起來不錯的特性。在上面我們使用了兩種類型的參數,string 和 int32,gflags 一共支持 5 種類型的命令行參數定義:

  • DEFINE_bool: 布爾類型
  • DEFINE_int32: 32 位整數
  • DEFINE_int64: 64 位整數
  • DEFINE_uint64: 無符號 64 位整數
  • DEFINE_double: 浮點類型 double
  • DEFINE_string: C++ string 類型

如果你希望支持更複雜的結構,比如 list,你需要通過自己做一定的定義和解析,比如字元串按某個分隔符分割得到一個列表。

每一種類型的定義和使用都跟上面我們的例子相似,有所不同的是 bool 參數,bool 參數在命令行可以不指定值也可以指定值,假如我們定義了一個 bool 參數 debug_switch,可以在命令行這樣指定:

? test ./gflags_test -debug_switch # 這樣就是 true

? test ./gflags_test -debug_switch=true # 這樣也是 true

? test ./gflags_test -debug_switch=1 # 這樣也是 true

? test ./gflags_test -debug_switch=false # 0 也是 false

  • 1
  • 2
  • 3
  • 4

所有我們定義的 gflags 變數都可以通過 FLAGS_ 前綴加參數名訪問,gflags 變數也可以被自由修改:

if (FLAGS_consider_made_up_languages)

FLAGS_languages += ",klingon";

if (FLAGS_languages.find("finnish") != string::npos)

HandleFinnish();

  • 1
  • 2
  • 3
  • 4

進階?同樣 Easy

定義規範

如果你想要訪問在另一個文件定義的 gflags 變數呢?使用 DECLARE_,它的作用就相當於用 extern 聲明變數。為了方便的管理變數,我們推薦在 .cc 或者 .cpp 文件中 DEFINE 變數,然後只在對應 .h 中或者單元測試中 DECLARE 變數。例如,在 foo.cc 定義了一個 gflags 變數 DEFINE_string(name, "bob", ""),假如你需要在其他文件中使用該變數,那麼在 foo.h 中聲明 DECLARE_string(name),然後在使用該變數的文件中 include "foo.h" 就可以。當然,這只是為了更好地管理文件關聯,如果你不想遵循也是可以的。

參數檢查

如果你定義的 gflags 參數很重要,希望檢查其值是否符合預期,那麼可以定義並註冊參數的值的檢查函數。如果採用 static 全局變數來確保檢查函數會在 main 開始時被註冊,可以保證註冊會在 ParseCommandLineFlags 函數之前。如果默認值檢查失敗,那麼 ParseCommandLineFlags 將會使程序退出。如果之後使用 SetCommandLineOption() 來改變參數的值,那麼檢查函數也會被調用,但是如果驗證失敗,只會返回 false,然後參數保持原來的值,程序不會結束。看下面的程序示例:

#include <stdint.h>

#include <stdio.h>

#include <iostream>

#include <gflags/gflags.h>

// 定義對 FLAGS_port 的檢查函數

static bool ValidatePort(const char* name, int32_t value) {

if (value > 0 && value < 32768) {

return true;

}

printf("Invalid value for --%s: %d
", name, (int)value);

return false;

}

/**

* 設置命令行參數變數

* 默認的主機地址為 127.0.0.1,變數解釋為 "the server host"

* 默認的埠為 12306,變數解釋為 "the server port"

*/

DEFINE_string(host, "127.0.0.1", "the server host");

DEFINE_int32(port, 12306, "the server port");

// 使用全局 static 變數來註冊函數,static 變數會在 main 函數開始時就調用

static const bool port_dummy = gflags::RegisterFlagValidator(&FLAGS_port, &ValidatePort);

int main(int argc, char** argv) {

// 解析命令行參數,一般都放在 main 函數中開始位置

gflags::ParseCommandLineFlags(&argc, &argv, true);

std::cout << "The server host is: " << FLAGS_host

<< ", the server port is: " << FLAGS_port << std::endl;

// 使用 SetCommandLineOption 函數對參數進行設置才會調用檢查函數

gflags::SetCommandLineOption("port", "-2");

std::cout << "The server host is: " << FLAGS_host

<< ", the server port is: " << FLAGS_port << std::endl;

return 0;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

讓我們運行一下程序,看看怎麼樣:

#命令行指定非法值,程序解析參數時直接退出

? test ./gflags_test -port -2

Invalid value for --port: -2

ERROR: failed validation of new value "-2" for flag "port"

# 這裡參數默認值合法,但是 SetCommandLineOption 指定的值不合法,程序不退出,參數保持原來的值

? test ./gflags_test

The server host is: 127.0.0.1, the server port is: 12306

Invalid value for --port: -2

The server host is: 127.0.0.1, the server port is: 12306

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用 flagfile

如果我們定義了很多參數,那麼每次啟動時都在命令行指定對應的參數顯然是不合理的。gflags 庫已經很好的解決了這個問題。你可以把 flag 參數和對應的值寫在文件中,然後運行時使用 -flagfile 來指定對應的 flag 文件就好。文件中的參數定義格式與通過命令行指定是一樣的。

例如,我們可以定義這樣一個文件,文件後綴名沒有關係,為了方便管理可以使用 .flags:

--host=10.123.14.11

--port=23333

  • 1
  • 2

然後命令行指定:

? test ./gflags_test --flagfile server.flags

The server host is: 10.123.14.11, the server port is: 23333

  • 1
  • 2

棒!以後再也不用擔心參數太多了~^_^

看到這裡,是不是覺得 gflags 對你的項目很有幫助?用起來吧,釋放超能力 :)

google gflags 庫完全使用

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Linux之索引式文件系統
基於SSM實現的簡易員工管理系統

TAG:程序員小新人學習 |