1、 gflags 是Google开源的命令行工具。命令行工具主要关注的是两个部分: flags 和 values。下面看,什么是flags,什么是values。
/usr/bin/myapp --name="nilboy"
在上面的命令行中,"name" 即是flags, “nilboy” 即是 values
2、在程序中,如何定义flags:
命令行的首要任务,即是将命令行中的变量值传递到程序中去。那么如何在程序中定义flags:
#include <gflags/gflags.h>
DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
DEFINE_string(languages, "english,french,german",
"comma-separated list of languages to offer in the 'lang' menu");
a : flag name
b : default value
c : help information(--help)在gflags的哲学里,认为使用简单的flag类型进行传递参数,比使用复杂的逻辑flag传递参数更好,所以,gflags的flag 类型仅仅有以下几种:
DEFINE_bool: booleanDEFINE_int32: 32-bit integerDEFINE_int64: 64-bit integerDEFINE_uint64: unsigned 64-bit integerDEFINE_double: doubleDEFINE_string: C++ string
3. 声明flags:
声明flags的语法如下:
DECLARE_bool(big_menu);其本质是:
extern bool FLAGS_big_menu。所以,很明显 声明flags的语句要放在.h 文件中,而定义flags的语句要放在.c or .cc 文件中。
3. 访问flags:
每个flags对应一个变量: 例如上面的两个flags对应的变量为:
FLAGS_big_menu FLAGS_languages
4. 如何从命令行中,读取flag和值到程序中:
google::ParseCommandLineFlags(&argc, &argv, true);参数:
argc: main函数参数
argv: main 函数参数
第三个参数: remove_flags
如果remove_flags = true,删除 argv 中所有flags 以及它们对应的参数,并且修改argc的值。
如果remove_flags = false, argc不变,调整argv 的顺序,具体顺序参考官方文档。
5. flags的value的验证:
通常情况下flags 都是需要验证它的value。
需要在main解析命令行参数之前,注册验证函数:
static bool ValidatePort(const char* flagname, int32 value) {
if (value > 0 && value < 32768) // value is ok
return true;
printf("Invalid value for --%s: %d\n", flagname, (int)value);
return false;
}
DEFINE_int32(port, 0, "What port to listen on");
static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
By doing the registration at global initialization time (right after the DEFINE), we ensure that the registration happens before the commandline is parsed at the beginning of main().

至于什么时候调用验证函数呢?每次通过 SetCommandLineOption()修改flag的值,或者命令行解析的时候,都会调用。如果默认或命令行解析时,validation函数返回false则报错;其他情况,返回false,则继续保持之前的值。
注:如果直接通过FLAGS_**改变flag的值,则不会调用validation函数。
6. 在命令行中传递参数的值的方法:
Note the atypical syntax for setting a boolean flag to false: putting "no" in front of its name. There's a fair bit of flexibility to how flags may be specified. Here's an example of all the ways to specify the "languages" flag:
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"
For boolean flags, the possibilities are slightly different:
app_containing_foo --big_menuapp_containing_foo --nobig_menuapp_containing_foo --big_menu=trueapp_containing_foo --big_menu=false
(as well as the single-dash variant on all of these).
推荐方法:
using only a single form: --variable=value for non-boolean flags, and --variable/--novariable for
boolean flags
==========================
#include <gflags/gflags.h>
#include <iostream>
using namespace std;
static bool ValidatePort(const char* flagname,google::int32 value){
if(value>0 && value<100)
return true;
return false;
}
DEFINE_int32(age,10,"aaaaaa");
static const bool dummy=google::RegisterFlagValidator(&FlAGS_age, &ValidatePort);//line a
int main(int argc,char *argv[]){
//google::RegisterFlagValidator(&FLAGS_age, &ValidatePort);
google::ParseCommandLineFlags(&argc, &argv, false);
cout<<FLAGS_age<<endl;
cout<<argc<<endl;
cout<<argv<<endl;
return 0;
}编译报错: line a FLAGS_age is not declared.
??????????????????????????????????????????????????????????????
Miscellaneous Notes
If your application has code like this:
#define STRIP_FLAG_HELP 1 // this must go before the #include! #include <gflags/gflags.h>
we will remove the help messages from the compiled source. This can reduce the size of the resulting binary somewhat, and may also be useful for security reasons.
1429

被折叠的 条评论
为什么被折叠?



