• gflg学习笔记


    gflag介绍

    gflag是一种用来读取命令行参数的东西,也可以从文件内读取多个命令行参数。

    定义flag

    使用gflags定义一个flag是非常简单的,只需要使用相应类型对应的宏定义即可,如下:

    #include 
    
    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");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上述的DEFINE宏包含有三个参数:1、flag的命名;2、flag的默认值;3、该flag对应的一些提示性说明(当用户传入—help 标志的时候向用户展现提示性说明)。只可以在一个文件中对某个flag进行定义,一旦在一个文件中给出定义之后,在其他文件中想要使用该flag,需要使用DECLARE宏来进行声明。

    通常在.cc文件中给出flag的定义,在.h文件中进行DECLARE声明,然后任何#include该.h文件的用户可以使用该flag。

    gflags还支持其他类型的定义:

    • DEFINE_string:C++string类型
    • DEFINE_int32:32位整形
    • DEFINE_int64:64位整形
    • DEFINE_uint64:64位无符号整形
    • DEFINE_double:double类型
    • DEFINE_bool:bool类型

    flag变量

    用DEFINE宏定义的flag都可以像普通的变量一样进行调用,定义的变量是以FLAGS_为前缀,如上述例子中定义了两个变量FLAGS_big_menu和FLAGS_languages,可以像普通的变量一样对其进行读写:

    if (FLAGS_consider_made_up_languages) 
        FLAGS_languages += ",klingon";   // implied by --consider_made_up_languages 
    if (FLAGS_languages.find("finnish") != string::npos) 
        HandleFinnish(); 
    
    • 1
    • 2
    • 3
    • 4

    gflag.h头文件中也给出了具体的get、set函数进行读写。

    在另外一个文件中如果想要使用上述定义的big_menu,只需要在该文件的头部进行如下声明:

    DECLARE_bool(big_menu); 
    
    • 1

    然而上述这种extern的声明方式表明了当前文件与flag定义文件之间的依赖关系,这种隐式的依赖关系不利于在大型工程项目中使用,所以官方给出了如下的使用规则:如果在.cc文件中定义了一个flag,要么不进行声明(除了.cc文件中没有其他文件使用该flag),要么只在测试需要用到的文件中或者在.h头文件中进行DECLARE进行声明。

    如果其他文件需要使用定义好的flag,就在.h头文件中进行DECLARE声明,然后只需要#include该头文件即可,这样是一种显示的依赖关系,并且该flag成为一个全局变量

    命令行设置flag

    定义flag的原因就是能够通过命令行传递一个值并且赋给相应的flag,而不是定义一个常量。gflags为我们提供了很多形式来给flag传递参数,但是建议采用如下方式:

    对于非bool类型的flag:

    --variable=value // --变量名
    
    • 1

    对于bool类型的flag:

    --variable/--novariable 
    
    • 1

    gflag基本用法

    1. 包含头文件: #include

    2. 此时一定不要忘记将main函数加入两个输入参数,argc和argv。在主函数中,加入gflags的初始化语句:gflags::ParseCommandLineFlags(&argc, &argv, true);

    3. 在代码运行的过程中,可以直接使用FLAG_{name}进行参数的获取。

    4. 使用DEFINE_string对字符串进行初始化,可以通过命令行参数对其值进行修改,如果想要引用其他文件中的变量,使用DECLARE_string(变量名)来对其进行extern,然后才能对其进行使用。(不建议)

    5. 如果想要将多个命令行参数写入文件中,一并读进程序中,在运行可执行文件的同时,使用–flagfile=“文件名”来进行调用文件。

    // demo.cpp
    #include 
    #include 
     
    using namespace std;
     
    DEFINE_string(confPath, "../conf/setup.ini", "program configure file.");
    DEFINE_int32(port, 9090, "program listen port");
    DEFINE_bool(daemon, true, "run daemon mode");
     
    int main(int argc, char** argv)
    {
      gflags::ParseCommandLineFlags(&argc, &argv, true);
     
      cout << "confPath = " << FLAGS_confPath << endl;
      cout << "port = " << FLAGS_port << endl;
     
      if (FLAGS_daemon) {
        cout << "run background ..." << endl;
      }
      else {
        cout << "run foreground ..." << endl;
      }
     
      cout << "good luck and good bye!" << endl;
     
      gflags::ShutDownCommandLineFlags();
      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
    1、上述代码运行结果:
    [amcool@leoox build]$ ./demo 
    confPath = ../conf/setup.ini
    port = 9090
    run background ...
    good luck and good bye!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2、设定参数值
    i)可以用 –参数名=参数值 或者 -参数名=参数值 的方式来设定参数值。
    ii)对于bool类型的参数,除了上述方式外,还可以用 –参数名 的方式设定为true(即不带值), 使用 –no参数名 的方式设定为false。为了统一,我建议都使用 上面的 第 i)种方法来设定参数。
    
    [amcool@leoox build]$ ./demo --port=8888 --confPath=./setup.ini --daemon=true  
    confPath = ./setup.ini
    port = 8888
    run background ...
    good luck and good bye!
    [amcool@leoox build]$ ./demo -port=8888 -confPath=./setup.ini -daemon=false
    confPath = ./setup.ini
    port = 8888
    run foreground ...
    good luck and good bye!
    [amcool@leoox build]$ ./demo -port=8888 -confPath=./setup.ini -daemon
    confPath = ./setup.ini
    port = 8888
    run background ...
    good luck and good bye!
    [amcool@leoox build]$ ./demo -port=8888 -confPath=./setup.ini -nodaemon
    confPath = ./setup.ini
    port = 8888
    run foreground ...
    good luck and good bye!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    3、从文件读入“命令行”参数
    命令行参数很多时,每次启动都要一个一个的输入,很麻烦。gflags已经帮我们解决了,用 **–flagfile=命令行文件.cmd** 的方式就可以了。param.cmd就是上面说的命令行文件。
    
    [amcool@leoox build]$ vi param.cmd 
    --port=8888
    --confPath=./setup.ini
    --daemon=true
    [amcool@leoox build]$ ./demo --flagfile=param.cmd
    confPath = ./setup.ini
    port = 8888
    run background ...
    good luck and good bye!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    版本号和帮助信息,我们一般使用程序的时候,都离不开两个参数 –version 和 –help。
    【注意:SetVersionString() 和 SetUsageMessage() 一定要在 ParseCommandLineFlags() 之前设定。】

    #include 
    #include 
     
    using namespace std;
     
    DEFINE_string(confPath, "../conf/setup.ini", "program configure file.");
    DEFINE_int32(port, 9090, "program listen port");
    DEFINE_bool(daemon, true, "run daemon mode");
     
    int main(int argc, char** argv)
    {
      gflags::SetVersionString("1.0.0.0");
      gflags::SetUsageMessage("Usage : ./demo ");
      gflags::ParseCommandLineFlags(&argc, &argv, true);
     
      cout << "confPath = " << FLAGS_confPath << endl;
      cout << "port = " << FLAGS_port << endl;
     
      if (FLAGS_daemon) {
        cout << "run background ..." << endl;
      }
      else {
        cout << "run foreground ..." << endl;
      }
     
      cout << "good luck and good bye!" << endl;
     
      gflags::ShutDownCommandLineFlags();
      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
    [amcool@leoox build]$ ./demo --version
    demo version 1.0.0.0
    [amcool@leoox build]$ ./demo --help
    demo: Usage : ./demo 
     
      Flags from /home/amcool/program/gflags/demo/demo.cpp:
        -confPath (program configure file.) type: string
          default: "../conf/setup.ini"
        -daemon (run daemon mode) type: bool default: true
        -port (program listen port) type: int32 default: 9090
     
      Flags from /home/amcool/soft/gflags-2.1.1/src/gflags.cc:
        -flagfile (load flags from file) type: string default: ""
        -fromenv (set flags from the environment [use 'export FLAGS_flag1=value'])
          type: string default: ""
        -tryfromenv (set flags from the environment if present) type: string
          default: ""
        -undefok (comma-separated list of flag names that it is okay to specify on
          the command line even if the program does not define a flag with that
          name.  IMPORTANT: flags in this list that have arguments MUST use the
          flag=value format) type: string default: ""
     
      Flags from /home/amcool/soft/gflags-2.1.1/src/gflags_completions.cc:
        -tab_completion_columns (Number of columns to use in output for tab
          completion) type: int32 default: 80
        -tab_completion_word (If non-empty, HandleCommandLineCompletions() will
          hijack the process and attempt to do bash-style command line flag
          completion on this value.) type: string default: ""
     
      Flags from /home/amcool/soft/gflags-2.1.1/src/gflags_reporting.cc:
        -help (show help on all flags [tip: all flags can have two dashes])
          type: bool default: false currently: true
        -helpfull (show help on all flags -- same as -help) type: bool
          default: false
        -helpmatch (show help on modules whose name contains the specified substr)
          type: string default: ""
        -helpon (show help on the modules named by this flag value) type: string
          default: ""
        -helppackage (show help on all modules in the main package) type: bool
          default: false
        -helpshort (show help on only the main module for this program) type: bool
          default: false
        -helpxml (produce an xml version of help) type: bool default: false
        -version (show version and build info and exit) type: bool default: false
    
    • 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
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    参考

    1. gflag使用
    2. Gflag使用
    3. 谷歌命令行解析工具gflags详解
  • 相关阅读:
    Leetcode 4.21
    vs中C++编译未生成exe
    Map和Set的区别
    JS-对象
    Kubernetes常用命令
    Elasticsearch学习系列二(基础操作)
    目标检测网络系列——YOLO V2
    《云原生-Kubernetes篇》深入剖析Kubernetes中pod的原理
    yolov8模型训练、目标跟踪
    【算法|动态规划No.32 | 完全背包问题】完全背包模板题
  • 原文地址:https://blog.csdn.net/weixin_44947987/article/details/126219040