菜鸟笔记
提升您的技术认知

google::ParseCommandLineFlags 介绍

google::ParseCommandLineFlagsGoogle C++ 命令行参数解析库(gflags) 中的核心函数,用于解析程序启动时传入的命令行参数(如 --port=8080--help 等),并自动将值赋给对应的全局变量。


一、gflags 简介

  • 项目地址https://github.com/gflags/gflags
  • 特点
    • 支持 --flag=value--flag value-flag value 等多种格式
    • 自动生成 --help 信息
    • 支持布尔、整数、字符串、浮点等多种类型
    • 线程安全(C++11 起)
    • 被广泛用于 Google 开源项目(如 TensorFlow、gRPC)

二、基本用法步骤

步骤 1:定义命令行标志(Flag)

使用宏 DEFINE_type(flag_name, default_value, "description") 在全局作用域声明:

#include <gflags/gflags.h>
#include <iostream>  
// 定义 flags 
DEFINE_string(server_ip, "127.0.0.1", "Server IP address");
DEFINE_int32(port, 8080, "Server port number");
DEFINE_bool(daemon, false, "Run in daemon mode");

✅ 支持的类型宏:

  • DEFINE_bool
  • DEFINE_int32DEFINE_uint64DEFINE_double
  • DEFINE_string

步骤 2:在 main() 中解析命令行参数

int main(int argc, char* argv[]) {     
    // 解析命令行参数     
    google::ParseCommandLineFlags(&argc, &argv, true); 
    // 使用 flag 值(通过 FLAGS_flagname 访问)     
    std::cout << "Server: " << FLAGS_server_ip << ":" << FLAGS_port << "\n";     
    if (FLAGS_daemon) {
        std::cout << "Running in daemon mode.\n";
    }  
    return 0; 
}

函数签名:

1void google::ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags);
  • argcargv:主函数参数
  • remove_flags
    • true:解析后从 argv 中移除已识别的 flag(剩余参数可用于其他用途)
    • false:保留所有参数

步骤 3:编译与运行

安装 gflags(Ubuntu/Debian):

sudo apt-get install libgflags-dev

编译:

g++ -std=c++11 main.cpp -lgflags -o myapp

运行示例:

./myapp --server_ip=192.168.1.100 --port=3000 --daemon 
# 输出: 
# Server: 192.168.1.100:3000 
# Running in daemon mode.

查看帮助:

./myapp --help

输出自动生成的帮助信息,包含所有 flag 及其默认值和描述。


三、完整示例

1// server.cc
2#include <gflags/gflags.h>
3#include <iostream>
4
5DEFINE_string(bind, "0.0.0.0", "IP to bind");
6DEFINE_int32(port, 8080, "Port to listen on");
7DEFINE_int32(workers, 4, "Number of worker threads");
8DEFINE_bool(verbose, false, "Enable verbose logging");
9
10int main(int argc, char* argv[]) {
11    // 解析命令行
12    google::ParseCommandLineFlags(&argc, &argv, true);
13
14    // 打印配置
15    std::cout << "Starting server on " << FLAGS_bind << ":" << FLAGS_port << "\n";
16    std::cout << "Workers: " << FLAGS_workers << "\n";
17    if (FLAGS_verbose) {
18        std::cout << "[INFO] Verbose mode enabled\n";
19    }
20
21    // 剩余未解析参数(因 remove_flags=true,这里 argc 应为 1)
22    for (int i = 1; i < argc; ++i) {
23        std::cout << "Extra arg: " << argv[i] << "\n";
24    }
25
26    return 0;
27}

运行:

./server --port=9000 --workers=8 --verbose extra_arg

remove_flags=true,则 extra_arg 会保留在 argv[1] 中(因为 --xxx 被移除了)。


四、高级用法

1. 在代码中修改 flag 值

FLAGS_port = 9090; // 允许运行时修改

2. 声明外部 flag(在多个文件中使用)

// config.h 
DECLARE_string(config_file); 
DECLARE_bool(debug);  
// main.cc 
DEFINE_string(config_file, "app.conf", "Config file path"); 
DEFINE_bool(debug, false, "Debug mode");

3. 自定义验证函数(C++11 起)

static bool ValidatePort(const char* flagname, int32_t value) {     
if (value > 0 && value < 65536) return true;     
    std::cerr << "Invalid value for --" << flagname << ": " << value << "\n";     
return false; 
}  
DEFINE_int32(port, 8080, "Port number"); 
static const auto port_dummy = gflags::RegisterFlagValidator(&FLAGS_port, &ValidatePort);