gflags支持的类型有bool,int32,int64,uint64,double和string。可以说这些基本类型大体上满足了我们的需求。

  1. DEFINE_bool: boolean
  2. DEFINE_int32: 32-bit integer
  3. DEFINE_int64: 64-bit integer
  4. DEFINE_uint64: unsigned 64-bit integer
  5. DEFINE_double: double
  6. DEFINE_string: C++ string

比如上文中,我就定义了confPath, port, daemon三个命令行参数,回顾一下:

 
1
2
3
;
;
;

稍微讲解一下:

  • 第一个字段 confPath就是命令行里要输入的参数名,比如 –confPath=./love.ini
  • 第二个字段”../conf/setup.ini”,就是如果命令行里没指定这个参数,那默认值就是 ../conf/setup.ini
  • 第三个字段”program configure file.”,就是这个参数的帮助说明信息,当用户输入 –hlep 的时候,会显示出来。

 

   代码中使用这个变量

以前我们使用getopt_long函数来自己解析命令行参数的时候,都得内部定义一个变量来保存从命令行得到的值。后续就可以使用这个变量来完成相应的代码逻辑。那其实,DEFINE_string等“指令”就相当于定义了变量,只不过变量名多了个前缀 “FLAGS_“。即,我们可以在代码里面直接操作FLAGS_confPath,FLAGS_port,FLAGS_port,FLAGS_daemon这三个变量。

 

    解析命令行参数

gflags是使用ParseCommandLineFlags这个方法来完成命令行参数的解析的。具体如下:

 
1
;

一目了然,唯一值得注意的就是第三个参数了。如果设置为true,gflags就会移除解析过的参数。即argc, argv就会变了。否则gflags还会保持这些参数继续留在argc,argv中。但是参数的顺序有可能会发生变化。

如果不好理解的话,没关系,来一段代码就明白什么意思了。

 
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
#include <iostream>
#include <gflags/gflags.h>
 
;
 
;
;
;
 
)
{
{
;
}
;
 
;
;
;
 
{
;
}
;
 
;
;
 
{
;
}
{
;
}
 
;
 
;
;
}

 

运行后,看一下true的情况:

 
1
2
3
4
5
6
7
8
9
10
11
12
daemon
demo
8888
ini
daemon
--
demo
--
ini
8888
.
!

 

修改为false,在运行一下的情况:

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
daemon  
demo
8888
ini
daemon
--
demo
8888
ini
daemon
--
ini
8888
.
!

 

    参数检查

按照以前的习惯,我们可以获取到所有参数的值后,再在代码里面进行判断这个参数是否是我们想要的。比如,我们需要端口是36800 到 36888之间的,那我们可以这样检查。

 
1
2
3
4
{
;
;
}

 

当然gflags里面建议使用 RegisterFlagValidator 这个方法来做参数检查。参数不通过的时候,程序是启动失败的。

 
1
2
3
4
5
6
7
8
9
10
11
{
{
;
;
}
 
;
;
}
;
;

 

运行一下,看看效果:

 
1
2
3
4
daemon
!
!
'port'

 

【疑问】:我们手动指定端口36889不合法,默认的36810合法。怎么让gflags当发现参数不合法的时候,使用合法的默认参数呢?!

 

    其他代码文件使用参数变量

正常来说,我们的代码不可能只有1个cpp,还会有很多模块。而每个模块可能会使用到不同的参数值。所以我们之前在demo.cpp定义的参数变量(比如FLAGS_port),在其他模块怎么引用和使用呢?so easy,与DEFINE相对应的有DECLARE。声明一下,就可以使用了。

  1. DECLARE_bool: boolean
  2. DECLARE_int32: 32-bit integer
  3. DECLARE_int64: 64-bit integer
  4. DECLARE_uint64: unsigned 64-bit integer
  5. DECLARE_double: double
  6. DECLARE_string: C++ string

 

来一段简单的代码,就一目了然啦。

     示例代码目录结构

 

 
1
2
3
4
5
6
7
8
9
10
tree
.
txt
build
cpp
cpp
h
 
files
$

 

    logic.h

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _LEOOX_LOGIC_H_
#define _LEOOX_LOGIC_H_
 
#include <iostream>
#include <gflags/gflags.h>
 
;
 
;
;
;
 
;
 
#endif

 

     logic.cpp

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
)
{
;
;
;
{
;
}
{
;
}
;
 
;
}

 

   demo.cpp

 

 
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
 
;
 
;
 
{
{
;
;
}
 
;
;
}
;
;
 
)
{
;
;
;
 
;
 
;
 
;
;
}

 

    CMakeLists.txt

 

 
1
2
3
4
5
6
7
8
9
10
)
)
)
 
)
)
)
 
)
)

 

    运行结果

 

 
1
2
3
4
5
6
7
8
9
10
ini
!
!
-
ini
36850
.
-
!
$

 

至此,Google的强大的开源组件之一的“gflags”,就算完成了深入浅出的学习了。自己以后可以把getopt_long深藏功与名了。哈哈。

 

转自:http://www.leoox.com/?p=275

相关文章: