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.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值