《Linux——gflags》

一、什么是gflags?

gflags 是一個由 Google 開發的命令行參數解析庫,主要用于在 C++(也支持其他語言)程序中便捷地處理命令行參數。它的核心作用是幫助開發者快速定義、解析和使用命令行選項,避免手動編寫繁瑣的參數解析邏輯。

比如你寫了個聊天軟件,我們指定 “端口 = 8080” 。但總有用戶會和我們的口味不一樣,用戶運行時可能指定“端口 = 9090,8888,8989…”,這時我們總不能根據每個用戶的端口號一個一個去判斷吧

有了 gflags,你只需用它的宏定義:

DEFINE_int32(port, 8080, "端口號");  // 定義端口參數,默認8080

然后調用一句解析函數,用戶輸入的 “–port=9000” 就會通過命令行對應到變量里,這時運行函數,宏定義的port就是9000,我們只需在終端就能改變程序參數值。(再次運行就會變成默認值。還能自動生成–help幫助信息,用戶輸入程序名–help就知道能傳哪些參數。)

二、Linux 下安裝 gflags

gflags 安裝非常簡單,支持 包管理器安裝 和 源碼編譯安裝 兩種方式,根據需求選擇即可。

1. 包管理器安裝)

Ubuntu/Debian 系列:

sudo apt update && sudo apt install -y libgflags-dev

CentOS/RHEL 系列:

sudo yum install -y gflags-devel

安裝完成后,頭文件默認位于 /usr/include/gflags/,庫文件位于/usr/lib/x86_64-linux-gnu/(Ubuntu)或 /usr/lib64/(CentOS)。

2. 源碼編譯安裝

如果需要使用 gflags 的最新特性(如自定義參數別名、配置文件讀取增強),可從 GitHub 源碼編譯:

# 下載源碼 
git clone https://github.com/gflags/gflags.git 
# 切換目錄 
cd gflags/
mkdir build 
cd build/ 
# 生成Makefile 
cmake .. 
# 編譯代碼 
make 
# 安裝 
make install

編譯完成后,頭文件和庫文件會被安裝到 /usr/local 目錄下。

三、實例

理論不如實踐,我們從一個最簡單的程序入手,感受 gflags 的核心用法。這個程序將解析 3 個常用參數:調試模式(布爾值)、服務端口(整數)、日志路徑(字符串)。

1. 編寫代碼

#include <iostream>
#include <gflags/gflags.h> DEFINE_bool(debug, false, "檢查程序是否正常啟動");
DEFINE_int32(port, 8080, "查看服務端端口號");
DEFINE_string(log_path, "./log", "查看當前日志路徑");int main(int argc, char** argv) {// 解析命令行參數:必須在使用參數前調用// 第三個參數為 true 表示解析后移除參數,argv 僅保留程序名和非參數參數gflags::ParseCommandLineFlags(&argc, &argv, true);std::cout << "debug: " << (FLAGS_debug ? "ON" : "OFF") << std::endl;std::cout << "port: " << FLAGS_port << std::endl;std::cout << "log_path: " << FLAGS_log_path << std::endl;return 0;
}

2. 編譯與運行

編譯時需要鏈接 gflags 庫(使用 -lgflags 選項):

g++ -o main main.cc -lgflags

運行程序并傳入參數,感受 gflags 的解析效果:

在這里插入圖片描述

3. 核心邏輯解析

  • 參數定義:通過 DEFINE_<類型> 宏聲明參數,無需手動寫解析邏輯。例如 DEFINE_bool(debug, false, “…”) 聲明了一個名為 debug 的布爾參數,默認值 false,幫助說明為括號內的字符串。
  • 參數解析:gflags::ParseCommandLineFlags(&argc, &argv, true) 是核心函數,負責解析命令行參數并填充到 FLAGS_<參數名> 變量中。
  • 參數訪問:直接通過 FLAGS_<參數名> 訪問解析后的值,類型與定義時一致(如 FLAGS_port 是 int32_t 類型)。

四、gflags特性及使用

掌握了基礎用法后,我們來深入了解 gflags 的幾個實用特性,讓參數解析更靈活。

1. 支持的參數類型

gflags 提供了 6 種常用類型的參數宏,覆蓋大部分開發場景:

宏定義類型用途示例
DEFINE_boolbool啟用 / 禁用功能(–debug)
DEFINE_int32int32_t32 位整數(–port=8080)
DEFINE_int64int64_t64 位整數(–max_conn=1000000)
DEFINE_uint64uint64_t無符號 64 位整數(–timeout=3600)
DEFINE_doubledouble浮點數(–threshold=0.95)
DEFINE_stringstd::string字符串(–log_path=/var/log)

2. 參數驗證:避免非法輸入

實際開發中,參數往往有合法范圍(如端口號必須在 1-65535 之間)。gflags 支持通過 DEFINE_validator 宏為參數綁定驗證函數,自動攔截非法輸入。
示例:為端口參數添加驗證
在之前的代碼中添加以下內容:

// 驗證函數:參數名(flagname)、參數值(value),返回 bool 表示是否合法
static bool ValidatePort(const char* flagname, int32_t value) {if (value > 0 && value < 65536) {  // 端口號合法范圍return true;}// 非法時輸出錯誤信息std::cerr << "Invalid value for --" << flagname << ": " << value << " (must be 1-65535)" << std::endl;return false;
}// 為 port 參數綁定驗證函數
DEFINE_validator(port, &ValidatePort);  // 格式:DEFINE_validator(參數名, 驗證函數)

測試非法參數:

./gflags_demo --port=70000  # 端口 70000 超出范圍
Invalid value for --port: 70000 (must be 1-65535)

3. 從配置文件讀取參數

gflags 支持從文件讀取參數,不用每次在命令行輸入一堆參數,特別方便。
先建個參數文件(比如叫 config.txt),里面寫參數(不用加 --):

-port=9000
-debug=true
-log_path=/var/log

運行程序時,用 --flagfile 指定這個文件:

./main --flagfile=config.txt

在這里插入圖片描述

4. 自動生成幫助信息

gflags 會自動為所有參數生成 --help 幫助信息,無需手動編寫。運行程序時添加 --help 即可查看:

./main --help

輸出幫助信息:
在這里插入圖片描述

可以看到,gflags 不僅顯示了我們自定義的參數,還自帶了 --helpfull(詳細幫助)、–version(版本信息)等通用參數。

五、常見問題

1. 編譯時提示 “找不到 gflags 庫”?

如果使用源碼編譯安裝 gflags,可能會出現鏈接器找不到庫文件的問題。解決方法:
編譯時指定庫路徑:

g++ -o demo demo.cpp -lgflags -L/usr/local/lib

若仍報錯,執行 sudo ldconfig 更新系統庫緩存(讓系統識別新安裝的 gflags 庫)。

2. 布爾參數的特殊用法

布爾參數支持三種寫法,效果相同:

./gflags_demo --debug        # 啟用(相當于 --debug=true)
./gflags_demo --nodebug      # 禁用(相當于 --debug=false)
./gflags_demo --debug=false  # 顯式指定 false

3.小技巧

  • 參數命名:使用全小寫 + 下劃線(如 log_path),符合命令行參數習慣。
  • 默認值合理性:為參數設置安全的默認值(如端口默認 8080,避免與系統端口沖突)。
  • 必選參數處理:gflags 不直接支持 “必選參數”,可在解析后手動檢查,例如:
if (FLAGS_log_path.empty()) {std::cerr << "Error: --log_path is required!" << std::endl;return 1;
}
  • 版本信息設置:通過 gflags::SetVersionString(“1.0.0”) 設置版本,配合 --version 參數使用:
int main(int argc, char** argv) {gflags::SetVersionString("1.0.0");  // 設置版本號gflags::SetUsageMessage("Usage: ./gflags_demo [options]");  // 設置用法提示gflags::ParseCommandLineFlags(&argc, &argv, true);// ...
}

最后,附上 gflags 官方倉庫地址,以便獲取最新版本和更多細節:gflags GitHub 倉庫

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96594.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96594.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96594.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編譯器的前端中端和后端

前面說的詞法分析和語法分析&#xff0c;確實是編譯器前端 (Front End) 最核心的兩個部分。但前端的工作還沒有結束。編譯器各階段劃分 一個完整的編譯器通常可以分為三個部分&#xff1a;前端、中端 (Middle End)、后端 (Back End)。 前端 (Front End) 核心職責: 理解源代碼。…

黑馬Java進階教程,全面剖析Java多線程編程,并發和并行,筆記02

黑馬Java進階教程&#xff0c;全面剖析Java多線程編程&#xff0c;并發和并行&#xff0c;筆記02 一、并發和并行 并發&#xff1a;在同一時刻&#xff0c;有多個指令在單個CPU上交替執行 并行&#xff1a;在同一時刻&#xff0c;有多個指令在多個CPU上同時執行 二、為什么有…

20250908 背包DP總結

引子 ~ 我們都有一個家&#xff0c;名字叫背包 ~ 背包DP 顧名思義&#xff0c;背包DP是用來解決背包最值問題的。題目會給出背包的容量&#xff0c;以及幾個物品的屬性&#xff0c;比如重量&#xff0c;價值&#xff0c;限額等等&#xff0c;具體是什么看題目。 01背包 01…

Redis持久化之RDB:快照機制原理、配置與最佳實踐

Redis持久化之RDB&#xff1a;快照機制原理、配置與最佳實踐 1. RDB持久化概述 1.1 什么是RDB RDB&#xff08;Redis Database&#xff09;是Redis的默認持久化方式&#xff0c;它在指定的時間間隔內生成數據集的快照&#xff08;snapshot&#xff09;&#xff0c;并將快照保…

daily notes[44]

文章目錄基礎references基礎 hello,world是幾乎所有編程語言的第一例子&#xff0c;rust也不例外。但和其它語言不一樣&#xff0c;Rust的源碼最好擁有自己的項目目錄。 $ mkdir ~/pro $ cd ~/pro $ mkdir helloWorld $ cd helloWorld源代碼文件名為main.rs&#xff0c;內容如…

JavaScript對象創建方式完全指南:從原始到現代的演進之路

前言 作為一名前端開發者&#xff0c;JavaScript中對象創建是很重要。在JavaScript這門基于原型的語言中&#xff0c;對象幾乎無處不在。今天&#xff0c;我將帶領大家回顧JavaScript對象創建的7種方式&#xff0c;從最原始的字面量到現代的ES6 class&#xff0c;每一步演進都解…

基于單片機的無線水塔監控系統設計(論文+源碼)

本設計為基于單片機的無線水塔監控系統設計&#xff0c;主要由以下幾部分組成&#xff1a;均采用STC89C52RC單片機為主控&#xff1b;主機&#xff1a;NRF24L01無線通訊模塊&#xff0c;1602LCD液晶顯示屏。從機&#xff1a;NRF24L01無線通訊模塊&#xff0c;水位傳感器&#x…

凌晨0-3點不睡,你熬的不是夜,是人生!

“熬夜”這個詞&#xff0c;早已成為現代生活的常態。有人為了工作加班到深夜&#xff0c;有人為了娛樂刷劇到天明&#xff0c;但你知道嗎&#xff1f;熬夜最“要命”的時間段&#xff0c;其實是凌晨0點到凌晨3點。別以為只是少睡幾個小時而已&#xff0c;這個時間段不睡&#…

大語言模型基石:Transformer

一、引言 如今火爆的 GPT、LLaMA、通義千問、ChatGLM 等大語言模型&#xff0c;背后都離不開一個核心架構——Transformer。 2017 年&#xff0c;Google 在論文《Attention Is All You Need》中首次提出 Transformer 模型&#xff0c;徹底改變了自然語言處理的發展方向。它摒…

【算法】【鏈表】160.相交鏈表--通俗講解

算法通俗講解推薦閱讀 【算法–鏈表】83.刪除排序鏈表中的重復元素–通俗講解 【算法–鏈表】刪除排序鏈表中的重復元素 II–通俗講解 【算法–鏈表】86.分割鏈表–通俗講解 【算法】92.翻轉鏈表Ⅱ–通俗講解 【算法–鏈表】109.有序鏈表轉換二叉搜索樹–通俗講解 【算法–鏈表…

MySQL——庫的操作

1、創建數據庫語法&#xff1a;CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name這里的CHARACTER SET表示指定數據庫采用的字符集…

Python ast模塊(Abstract Syntax Trees,抽象語法樹)介紹及使用

文章目錄 核心概念 基本使用流程 常用節點類型 示例代碼 實際應用場景 注意事項 `ast.literal_eval()` 功能說明 適用場景 使用示例 限制與安全特性 與 `eval()` 的對比 總結 Python 的 ast 模塊( Abstract Syntax Trees,抽象語法樹)允許你解析、分析和修改 Python 代碼的…

C++寬度優先搜索算法:隊列與優先級隊列

本期我們就來深入學習一下C算法中一個很重要的算法思想&#xff1a;寬度優先搜索算法 寬度優先算法是一個應用十分廣泛的算法思想&#xff0c;涉及的領域也十分繁多&#xff0c;因此本篇我們先只涉獵它的一部分算法題&#xff1a;隊列/優先級隊列&#xff0c;后續我們會進一步地…

類的property屬性

??Python 中的 property 特性詳解??property 是 Python 中用于??將方法轉換為屬性??的裝飾器&#xff0c;它允許開發者以訪問屬性的方式調用方法&#xff0c;同時可以添加邏輯控制&#xff08;如數據校驗、計算屬性等&#xff09;。以下是其核心用法和優勢&#xff1a;…

【Redis#9】其他數據結構

引言 Redis 除了我們最常用的 String、Hash、List、Set、ZSet&#xff08;Sorted Set&#xff09; 這五種基本數據結構外&#xff0c;還提供了很多高級或特殊用途的數據結構/類型 &#xff0c;它們可以滿足更復雜的業務需求。 ? Redis 的“五大基本數據結構”回顧類型特點Stri…

AutoGen——自定義Agent

目錄引子自定義 AgentCountDownAgentArithmeticAgent在自定義 Agent 中使用自定義模型客戶端讓自定義 Agent 聲明式化Selector Group Chat示例&#xff1a;網頁搜索 / 數據分析代理&#xff08;Agents&#xff09;Workflow終止條件&#xff08;Termination Conditions&#xff…

【重定向和轉發的核心理解】

重定向和轉發 不廢話&#xff1a; “轉發” 的核心定義&#xff1a; 服務端內部主導跳轉、客戶端無感知&#xff08;僅 1 次請求&#xff09;、瀏覽器 URL 不改變&#xff0c;與傳統 Web 開發中 “轉發” 的本質邏輯完全一致&#xff0c;只是實現載體&#xff08;Nginx 路由層 …

生成對抗網絡詳解與實現

生成對抗網絡詳解與實現0. 前言1. GAN 原理2. GAN 架構3. 損失函數3.1 判別器損失3.2 生成器損失3.4 VANILLA GAN4. GAN 訓練步驟0. 前言 生成對抗網絡 (Generative Adversarial Network, GAN) 是圖像和視頻生成中的主要方法之一。在本節中&#xff0c;我們將了解 GAN 的架構、…

FPGA硬件開發-XPE工具的使用

目錄 XPE 工具概述? XPE 使用步驟詳解? 1. 工具獲取與初始化? 2. 器件選擇與配置? 3. 電源電壓設置? 4. 資源使用量配置? 5. 時鐘與開關活動配置? 6. 功耗計算與報告生成? 報告解讀與電源設計優化? 常見問題與最佳實踐? 與實際功耗的差異處理? 工具版本…