gflags学习

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");

以上定义了两个flags,Define_xxx(a,b,c)的三个参数a,b,c的意义分别是:

a :  flag name
b :  default value
c  : help information(--help)

在gflags的哲学里,认为使用简单的flag类型进行传递参数,比使用复杂的逻辑flag传递参数更好,所以,gflags的flag 类型仅仅有以下几种:

  • 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
在gflags里,定义flag可以发生在程序的任何地方,甚至是在不同文件中,其本质就是定义全局变量,所以,出了定义flags之外,很自然,就需要声明flags。

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_menu
  • app_containing_foo --nobig_menu
  • app_containing_foo --big_menu=true
  • app_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.



你可能感兴趣的:(gflags学习)