google开源的gflags是一套命令行参数解析工具,比getopt功能更强大,使用起来更加方便,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的使用,内容主要译自 http://gflags.googlecode.com/svn/trunk/doc/gflags.html 。

定义参数

使用flags需要包含头文件

#include <gflags/gflags.h>

gflags主要支持的参数类型包括bool,int32, int64, uint64, double, string等,定义参数通过DEFINE_type宏实现,如下所示,分别定义了一个bool和一个string类型的参数,该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。

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

gflag不支持列表,用户通过灵活借助string参数实现,比如上述的languages参数,可以类型为string,但可看作是以逗号分割的参数列表。

访问参数

当参数被定义后,通过FLAGS_name就可访问到对应的参数,比如上述定义的big_menu、languages两个参数就可通过FLAGS_big_menu、FLAGS_languages访问。

if (FLAGS_languages.find("english") != string::npos) HandleEnglish(); 

以上的访问方式,仅在参数定义和访问在同一个文件(或是通过头文件包含)时,FLAGS_name才能访问到参数,如果要访问其他文件里定义的参数,则需要使用DECLARE_type。比如在foo.cc中DEFINE_string(color, "red", "the color you want to use"); 这时如果你需要在foo_test.cc中使用color这个参数,你需要加入DECLARE_string(color, "red", "the color you want to use");

参数检查

定义参数后,可以给参数注册一个检查函数(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); 

建议在定义参数后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true;如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。

初始化参数

在引用程序的main()里通过 google::ParseCommandLineFlags(&argc, &argv, true); 即完成对gflags参数的初始,其中第三个参数为remove_flag,如果为true,gflags会移除parse过的参数,否则gflags就会保留这些参数,但可能会对参数顺序进行调整。 比如 "/bin/foo" "arg1" "-q" "arg2"  会被调整为 "/bin/foo", "-q", "arg1", "arg2",这样更好理解。

#include <iostream>
#include <gflags/gflags.h>DEFINE_bool(isvip, false, "If Is VIP");
DEFINE_string(ip, "127.0.0.1", "connect ip");
DECLARE_int32(port);
DEFINE_int32(port, 80, "listen port");int main(int argc, char** argv)
{google::ParseCommandLineFlags(&argc, &argv, true);std::cout<<"ip:"<<FLAGS_ip<<std::endl;std::cout<<"port:"<<FLAGS_port<<std::endl;if (FLAGS_isvip){std::cout<<"isvip:"<<FLAGS_isvip<<std::endl;}google::ShutDownCommandLineFlags();return 0;
}

链接时使用 -gflags ,运行使用 ./gflags -ip="211.152.52.106" -port=8080 -isvip=true ,但是很遗憾,使用 valgrind 检测有内存泄漏。

输出结果如下:

ip:211.152.52.106
port:8080
isvip:1

在命令行指定参数

比如要在命令行指定languages参数的值,可通过如下4种方式,int32, int64等类型与string类似。

  • 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"

对于bool类型,则可通过如下几种方式指定参数

  • app_containing_foo --big_menu
  • app_containing_foo --nobig_menu
  • app_containing_foo --big_menu=true
  • app_containing_foo --big_menu=false

特殊参数

  • --help 打印定义过的所有参数的帮助信息
  • --version 打印版本信息 通过google::SetVersionString()指定
  • --nodefok  但命令行中出现没有定义的参数时,并不退出(error-exit)
  • --fromenv 从环境变量读取参数值 --fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过export FLAGS_foo=xxx; export FLAGS_bar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。
  • --tryfromenv 与--fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)
  • --flagfile 从文件读取参数值,--flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过--flagfile来包含其他的文件。

Caffe实例解析:

以 tools/caffe.cpp 为例分析gflags使用方法
在tools/caffe.cpp中首先包含了gflags的头文件

#include <gflags/gflags.h>

命令行参数传递

接下来定义了一些需要从命令行传递参数的变量

DEFINE_string(gpu, "","Optional; run in GPU mode on given device IDs separated by ','.""Use '-gpu all' to run on all available GPUs. The effective training ""batch size is multiplied by the number of devices.");
DEFINE_string(solver, "","The solver definition protocol buffer text file.");
DEFINE_string(model, "","The model definition protocol buffer text file.");
DEFINE_string(phase, "","Optional; network phase (TRAIN or TEST). Only used for 'time'.");
DEFINE_int32(level, 0,"Optional; network level.");
......

这些参数使用gflags提供的宏:DEFINE_xxx(变量名,默认值,help_string)。这些变量需要在全局范围内定义。变量支持以下类型:

定义  类型
DEFINE_bool 布尔型
DEFINE_int32 32位整形
DEFINE_int64 64位整形
DEFINE_uint64 64位无符号整形
DEFINE_double double型
DEFINE_string C++中string类型

在main函数中调用的GlobalInit()函数中调用了ParseCommandLineFlags()

// Google flags.
::gflags::ParseCommandLineFlags(pargc, pargv, true);

这个函数的作用就是解析命令行参数。 
pargc,pargv为命令行传递的参数个数和参数表,第三个参数作用为:

作用
true 函数处理完成后,argv中只保留argv[0],argc会被设置为1。
false argv和argc会被保留,但是注意函数会调整argv中的顺序。

执行完这参数后,就可以用FLAGS_xxx访问变量了。 
例如caffe.cpp中, FLAGS_solve表示命令行参数传递的模型文件,FLAGS_weights表示令行参数传递的权值文件

// Train / Finetune a model.
int train() {CHECK_GT(FLAGS_solver.size(), 0) << "Need a solver definition to train.";CHECK(!FLAGS_snapshot.size() || !FLAGS_weights.size())<< "Give a snapshot to resume training or weights to finetune ""but not both.";

帮助信息

gflags::SetUsageMessage函数用于设置命令行帮助信息。

// Usage message.gflags::SetUsageMessage("command line brew\n""usage: caffe <command> <args>\n\n""commands:\n""  train           train or finetune a model\n""  test            score a model\n""  device_query    show GPU diagnostic information\n""  time            benchmark model execution time");

设置帮助信息后,当参数错误或加 -help选项是可以打印帮助信息

$ ./build/tools/caffe
caffe: command line brew
usage: caffe <command> <args>commands:train           train or finetune a modeltest            score a modeldevice_query    show GPU diagnostic informationtime            benchmark model execution time
...

版本信息

gflags::SetVersionString用于设置版本信息

  // Set versiongflags::SetVersionString(AS_STRING(CAFFE_VERSION));

这里的CAFFE_VERSION是在Makefile中定义的 
当命令行参数加 -version 时会打印版本信息

$ ./build/tools/caffe -version

caffe version 1.0.0-rc3

【C++】gflags的使用相关推荐

  1. google gflags的参数解析,便捷实用

    命令行参数解析,一直是我们后段开发人员需要经常使用的一个功能,用来从终端解析接口的输入 ,并做出对应的处理.这里为使用C++/python的开发人员推荐一个便捷的命令行解析接口集 gflags. 我们 ...

  2. 【C++】google gflags详解

    参考博客:https://blog.csdn.net/lezardfu/article/details/23753741 0.简介 gflags是google的一个开源的处理命令行参数的库,使用c++ ...

  3. Google Gflags使用

    Google Gflags可以用于参数传递,它是以全局变量的形式进行参数传递,即代码中任何一处都可以调用到它.同时它也提供规范化的参数解析,可以用于主函数的传参. 定义 #include <gf ...

  4. 使用PageHeap.EXE或GFlags.EXE检查内存越界错误 (转)

    2011-05-27 20:19 290人阅读 评论(0) 收藏 举报 microsoftdebuggingstructureoutputimagefile 必先利其器之一:使用PageHeap.EX ...

  5. 【C++】34. gflags中的 --flagfile= 用法

    如果要把代码中的变量做成可通过配置文件进行配置的,可以使用gflag来实现. 如,想要通过代码运行 FLAGS_apple_nums可以这样定义: DECLARE_int32(apple_nums); ...

  6. gflags调试访问越界

    2011-9-27 烛秋 昨天.今天调dump,对windbg相当的不熟悉,但也慢慢的知道了一些常用的命令,几周前听说到有gflags这样个工具,今天正好测试下. gflags.exe是<Deb ...

  7. Caffe2 Compilation Error gflags.cc' is being linked both statically and dynamically into this execut

    问题描述 python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" | ...

  8. 使用 Google gflags 简化命令行参数处理

    (本文章仅适用于C++程序) 写服务程序时,如果需要提供命令行参数.传统的方法是手工解析argv参数,或者使用getopt函数.两种方法都比较费劲.使用Google gflags可以大大简化命令行参数 ...

  9. 安装glog和gflags

    1.下载 git clone https://github.com/google/glog 2.配置 sudo apt-get install autoconf automake libtool 3. ...

  10. gflags.lib(gflags.obj) : error LNK2001: 无法解析的外部符号 __imp_PathMatchSpecA

    问题描述: 在用gflags库时,生成提示错误: gflags.lib(gflags.obj) : error LNK2001: unresolved external symbol __imp__P ...

最新文章

  1. 厚积薄发的90后:读博前三年零文章,后期发力产出11篇一作,现任985高校博导...
  2. android studio 使用SVN 锁定文件,防止别人修改(基于Android studio 1.4 )
  3. POJ 1979 Red and Black (简单dfs)
  4. 一站式体验腾讯云音视频及融合通信技术
  5. 银盒子扫码下单在线订单开启商品售卖时段使用说明
  6. console.log()与alert()的区别
  7. C++使用简单的函数指针
  8. 百度编辑器 ueditor .net开发
  9. Flink Batch SQL 1.10 实践
  10. 在C7000+VMware vSphere5.5环境中的基础架构服务器部署实例
  11. 跑python gpu利用率低_提高GPU利用率,阿里云cGPU容器技术助力人工智能提效降本...
  12. SRIO IP的学习与应用
  13. 常见的网上商城系统开发语言有哪些?
  14. 夫水之积也不厚,则其负大舟也无力
  15. 2-10配置Linux网络
  16. 使用计算机时要注意防,计算机使用的几个基本技巧
  17. c语言的vcl库函数下载,VCL手册 PDF
  18. Vuex中的actions的参数
  19. python,基础-字符串(1)
  20. matlab中的箭头符号怎么打开,MATLAB中上下标、斜体、箭头等符号的使用方法

热门文章

  1. IP网络性能测试工具——Renix Perf
  2. 修改Android模拟器的IMEI号
  3. 考研计算机专业课961考什么,北航计算机考研(961)经验谈
  4. ydui倒计时:time_最后的倒计时:部署我的深度学习项目
  5. 微信小程序实现网络请求API获取数据
  6. python3爬虫系列20之反爬需要登录的网站三种处理方式
  7. 说说3D打印培训课程在我国的开展的现状——3D打印培训宁波清车
  8. Installation for COMSOl(安装COMSOL)
  9. xps文件服务器端,黑苹果从入门到精通 篇七:XPS 9360完美黑果实战
  10. 微商怎么做大做强,教你一套做微商全新打法