gflags(google開源的一套命令列引數解析工具)
gflags是google開源的一套命令列引數解析工具,比getopt()函式功能要強大,使用起來更加方便,gflags還支援從環境變數和配置檔案中讀取引數。目前有C++和Python版本。本文就來詳細介紹C++版本gflags的使用,主要分如下兩個部分
Contents
1. gflags的安裝
2. gflags的使用介紹
Github上code:
C++:https://github.com/gflags/gflags
python:https://github.com/gflags/python-gflags
1. gflags的安裝
上面我們已經對gflags
使用的版本是gflags-1.0rc2.tar.gz,然後進行解壓,執行如下3步
(1)./configure
(2)make
(3)make install
介紹兩個比較重要的檔案
doc : gflags的幫助檔案,裡面介紹了gflags的一些使用方法。
src : gflags的程式碼原始檔。
為了程式在執行時能載入libgflags.so檔案,還需要在/usr/lib目錄下建立軟連結,如下
現在就徹底安裝好gflags了,可以安心使用。
2. gflags的使用介紹
(1)定義引數
使用gflags需要包含標頭檔案#include <gflags/gflags.h>。而gflags支援的引數型別有
DEFINE_bool: boolean
DEFINE_int32: 32-bit integer
DEFINE_int64: 64-bit integer
DEFINE_uint64: unsigned 64-bit integer
DEFINE_double: double
DEFINE_string: C++ string
定義方式如下
即DEFINE_type就可以了,該巨集的三個引數分別代表命令列引數名,引數預設值,引數的幫助資訊。
gflags不支援列表,但是可以藉助string型別實現,比如
(2)引數訪問
引數被定義後,可以通過FLAGS_name來訪問,比如
注意一點,通過DEFINE定義的引數,要保證訪問變數的檔案和定義引數的檔案是同一個檔案或者是標頭檔案
包含關係,否則將會訪問不到定義的引數。在其它檔案使用定義的引數通過DECLARE實現。
(3)引數檢查
引數定義後,可以為引數註冊一個檢查函式,當從命令列指定引數或通過SetCommandLineOption()指定
引數時,檢查函式就會被呼叫,兩個引數分別為命令列引數名,以及設定的引數值。
- #include <iostream>
- #include <string.h>
- #include <string>
- #include <stdio.h>
- #include <gflags/gflags.h>
- usingnamespace std;
- usingnamespace google;
- staticbool ValidatePort(constchar *flagname, int32_t val)
- {
- if(val > 0 && val < 32768)
- returntrue;
- returnfalse;
- }
- DEFINE_int32(port, 6379, "what is the port ?");
- int main(int argc, char **argv)
- {
- ParseCommandLineFlags(&argc, &argv, true);
- bool isPort = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
- return 0;
- }
建議在定義引數後,立即註冊檢查函式。RegisterFlagValidator()在檢查函式註冊成功時返回true;
如果引數已經註冊了檢查函式,或者檢查函式型別不匹配,返回false。
(4)初始化引數
在引用程式的main()裡通過呼叫ParseCommandLineFlags(&argc, &argv, true)實現,即完成對gflags引數的初始化,最後一個引數如果為true,gflags會移除Parse過的引數,如果為false則會保留。可能會對引數順序進行調整。 比如 "/bin/foo" "arg1" "-q" "arg2" 會被調整為 "/bin/foo", "-q", "arg1", "arg2",這樣更好理解。
(5)在命令列指定引數
可以通過:--引數名=引數值 來指定。
- app_containing_foo --languages="chinese,japanese,korean"
- app_containing_foo -languages="chinese,japanese,korean"
- app_containing_foo --languages "chinese,japanese,korean"
- app_containing_foo -languages "chinese,japanese,korean"
對於bool型別,則可通過如下幾種方式指定引數
- app_containing_foo --big_menu
- app_containing_foo --nobig_menu
- app_containing_foo --big_menu=true
- app_containing_foo --big_menu=false
例如下面程式碼
- #include <iostream>
- #include <string.h>
- #include <string>
- #include <stdio.h>
- #include <gflags/gflags.h>
- usingnamespace std;
- usingnamespace google;
- staticbool ValidatePort(constchar *flagname, int32_t val)
- {
- if(val > 0 && val < 32768)
- returntrue;
- returnfalse;
- }
- DEFINE_int32(port, 6379, "what is the port ?");
- DEFINE_string(ip, "127.0.0.1", "My ip ?");
- int main(int argc, char **argv)
- {
- ParseCommandLineFlags(&argc, &argv, true);
- bool isPort = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
- int32_t Port = FLAGS_port;
- string Ip = FLAGS_ip;
- cout << Port << endl;
- cout << Ip << endl;
- return 0;
- }
引數可以通過下面方式指定,引數之間可以沒有順序。
(5)一些特殊的引數認識
--help
列印定義過的所有引數的幫助資訊
--version
列印版本資訊 通過google::SetVersionString()指定
--nodefok
但命令列中出現沒有定義的引數時,並不退出(error-exit)
--fromenv
從環境變數讀取引數值 --fromenv=foo,bar表明要從環境變數讀取foo,bar兩個引數的值。通過
export FLAGS_foo=xxx; export FLAGS_bar=yyy 程式就可讀到foo,bar的值分別為xxx,yyy。
--tryfromenv
與--fromenv類似,當引數的沒有在環境變數定義時,不退出(fatal-exit)
--flagfile
從檔案讀取引數值,--flagfile=my.conf表明要從my.conf檔案讀取引數的值。在配置檔案中指定參
數值與在命令列方式類似,另外在flagfile裡可進一步通過--flagfile來包含其他的檔案。