gflags是google一个开源的处理命令行参数的库,相比getopt,更加容易使用。
-
定义参数
gflags主要支持的参数类型包括 DEFINEbool: boolean DEFINEint32: 32-bit integer DEFINEint64: 64-bit integer DEFINEuint64: unsigned 64-bit integer DEFINEdouble: double DEFINEstring: C++string 定义参数通过DEFINE_type宏实现,
该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。
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_name就可访问到对应的参数。
如果使用时不想在main文件里定义flag,例如需要在flag1.cpp flags.cpp里定义,可以分别声明和定义:
在flags1.cpp flags2.cpp里分别定义各自的flag,然后在flag.h声明,需要使用的文件直接include flags.h
就可以了。
声明的函数如下:DECLARE_bool(big_menu)
- 解析参数
gflags::ParseCommandLineFlags(&argc, &argv, remove_flags)解析出相应 flags.
remove_flags: 若设置为true,表示解析后将flag以及flag对应的值从argv中删除,并相应的修改argc,即最后存放的是不包含flag的参数。如果设置为false,则仅对参数进行重排,标志位参数放在最前面。
也可以在命令行传入--flagfile
或者在程序里设置flagfile
以解析文件中的flags。
google::SetCommandLineOption("flagfile", "gflags_sample.flags");
FLAGS_flagfile
更新后,会自动重新读取该文件并更新文件里的gflags。
-
参数检查
定义参数后,可以给参数注册一个检查函数(validator) 当从命令行指定参数或通过SetCommandLineOption()指定参数时,检查函数就会被调用,两个参数分别为命令行参数名,以及设置的参数值。
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);
如果注册成功,regist函数返回值为ture。否则返回false,注册失败一般是一下两种原因:
- 第一个参数不是flag
- 该flag已经注册过
使用GetCommandLineFlagInfo判断一个 FLAG是否被设置
google::CommandLineFlagInfo info;
if (GetCommandLineFlagInfo("portno", &info) && info.is_default) {
std::cout << "port is not set." << std::endl;
} else {
std::cout << "port is set." << std::endl;
}
实际项目里,我们使用gflag替代了传统conf配置,其中有一个需求是配置可以动态reload的。
比较合理的是使用SetCommandLineOption
,函数原型为
extern std::string SetCommandLineOption(const char* name, const char* value);
注意bool int类型都使用字符串的方式修改,例如:
google::SetCommandLineOption("bvar_dump", "true")
google::SetCommandLineOption("portno", "9999")
特殊参数
--help 打印定义过的所有参数的帮助信息 --version 打印版本信息 通过google::SetVersionString()指定 --nodefok 但命令行中出现没有定义的参数时,并不退出(error-exit) --fromenv 从环境变量读取参数值 --fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过export FLAGSfoo=xxx; export FLAGSbar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。 --tryfromenv 与--fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit) --flagfile 从文件读取参数值,--flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过--flagfile来包含其他的文件。
google::SetCommandLineOption("flagfile", "./conf/gflags.conf");
参考:https://izualzhy.cn/gflags-introduction