• Gflags学习笔记


    简介

    Gflags是一套命名行处理的开源库,支持C++和Python,这里我主要学习C++上的应用。与getopt相比,Gflags具有更好的灵活性,可以在任意位置定义flags。

    使用步骤:

    1

    定义flag。flag的定义需要使用到gflags.h中的宏。gflags为用户提供了多种可以定义的flags类型,类型如下

    宏语句flag类型
    DEFINE_stringstring字符串类型
    DEFINE_int3232位整型
    DEFINE_int6464位整型
    DEFINE_uint6464位无符号整型
    DEFINE_double64位双浮点型
    DEFINE_bool布尔类型

    以string类型为例,一个完整的定义语句共包括三部分,分别是flag的名称,默认值和说明,其中说明是在用户使用–help时的描述内容。
    需要注意的是,由于名称对应的是变量名,因此不用加双引号,而默认值与说明均为一段字符串,因此都要加双引号。

    DEFINE_string(name, "minminwang", "please input your name")
    
    • 1

    2

    flag的布局。一个flag只可以被定义一次,如果想要在其他文件中使用已经定义的flag,需要使用到另一个宏DECLARE。每一种类型的flag都有一个对应的DECLARE宏。

    为了降低文件之间的相互依赖,Gflags的使用一般需要在一个.c文件中使用DEFINE宏定义相关的flag,然后在.h文件中使用DECLARE宏进行声明,这样每个include这一.h文件的地方都可以使用全部的flag。

    DECLARE_string(name)
    
    • 1

    3

    flag变量。每声明一个flag时都会生成一个与之对应的flag变量,可以直接通过FLAG_flag_name的方式来获取改变量,变量类型取决于声明时所使用的宏类型,可以像正常变量一样对其进行操作。例如通过上述语句,我们就得到了一个名为FLAG_name的flag变量。在其他文件中,使用DECLARE宏之后就可以使用该flag变量。DECLARE语句等效于extern FLAG_name但这样会形成一种隐式的依赖关系,不推荐使用。

    4

    flag验证器。Gflags允许为每个flag注册一个验证器,可以在每次获取flag值之后对其格式或内容就行校验。验证器的注册格式为DEFINE_validator(flag名称,&验证函数)。一个简单的验证月份的验证器的注册方式如下:

    static bool validateMonth(const char* flagname, int32 month){
    	if (month >= 1 && month <= 12) {
    		return true;
    	} else {
    		printf("%d is not a %s!\n", (int)month, flagname);
    		return false;
    	}
    }
    
    DEFINE_int32(month, 1, "a month in a year");
    DEFINE_validator(month, &validateMonth);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5

    flag参数的初始化。在flag参数定义完成之后,需要在main函数中通过命令行的输入对其进行初始化,具体可以使用google:ParseCommandLineFlags函数完成。该函数的输入共有三个,分别为argc,argv和remove_flags。其中argc与argv均为main函数的输入值,对应的是命令行的输入,由于在google::ParseCommandLineFlags函数中需要对这些参数进行修改,因此使用指针传递。remove_flags是一个bool类型的变量,当remove_flags为true时,ParseCommandLineFlags函数会在argv中移除标识与参数,只保留命名行参数,并将argc的值相应减小;而当其值为false时,ParseCommandLineFlags会在argv中保留参数和标识,只是将其移动到命令行参数的前面,同时argc不变。

    ./sample.sh --name="minminwang" --age=18 "daydayup" // --name和--age均为标识,minminwang和18为对应的参数,daydayup为命令行参数。
    
    static bool validateAge(const char* flagname, int32 age){
    	if (age >=0 && age<=100) {
    		return ture;
    	} else {
    		printf("Invalid %s: %d", flagname, (int)age);
    		return false;
    	}
    }
    
    DEFINE_stirng(name, "", "the name of user.");
    DEFINE_int32(age, 0, "the age of user.");
    DEFINE_validator(age, &vallidateAge);
    
    main(int argc, char* argv){  // 此时argc=3,argv="--name=minminwang --age=18 daydayup"
    	google::ParseCommandLineFlags(&argc, &argv, true);  // 之后argc=1, argv="daydayup"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6

    通过命令行设置flag的值。

    // 对于bool类型的flag共有四种方式
    --sex
    --sex=true
    --nosex
    --sex=false
    // 对于其他类型的flag也有四种方式
    --name="minminwang"
    -name="minminwang"
    --name "minminwang"
    -name "minminwang"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7

    特殊标识。

    --help  显示文件中所有标识的完整帮助信息
    --helpfull  和-help 一样,
    --helpshort  只显示当前执行文件里的标志
    --helpxml  以 xml 凡是打印,方便处理
    --version  打印版本信息,由 google::SetVersionString()设定
    --flagfile  -flagfile=f 从文件 f 中读取命令行参数
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例代码分析

    #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");
    
    int main(int argc, char **argv) {
      google::ParseCommandLineFlags(&argc, &argv, true);
    
      cout << "argc=" << argc << endl;
      if (FLAGS_big_menu) {
        cout << "big menu is ture" << endl;
      } else {
        cout << "big menu is flase" << endl;
      }
    
      cout << "languages=" << FLAGS_languages << endl;
      return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 相关阅读:
    OSG 添加文字(显示中英文)
    在基于乐鑫芯片的用户定制开发板上开发 UI
    超详细的ROC曲线绘制教程
    如何系列 如何玩转远程调用之OpenFegin+SpringBoot(非Cloud)
    数字秒表VHDL实验箱精度毫秒可回看,视频/代码
    【PAT甲级】1058 A+B in Hogwarts
    Coremail邮件安全:如何防范校园邮件新威胁
    MyBatis逆向工程和分页插件
    uniapp 实现下拉筛选框 二次开发定制
    3.机器学习-十大算法之一线性回归算法(LinearRegression)原理讲解
  • 原文地址:https://blog.csdn.net/qq_35630121/article/details/128205806