一、gflags簡單介紹
gflags是google開源的一套命令行參數解析工具。通常在項目開發中會有一種需求:
- 可以在代碼運行的時候指定某些代碼中某些參數的值
- 如果沒有顯式指定,這些參數可以使用默認的值
比如:服務器編程中需要用到IP和端口號。但是這兩個變量有時候在具體使用程序的時候纔會有具體的值,如果不用gflags可以這麼寫:
//test.cc
#include <iostream>
#include <string>
//else header file
#define LOG
class Server{
public:
Server(const std::string& ip = "127.0.0.1" , uint16_t port = 8080) : _ip(ip), _port(port) {
std::cout << "Init Server..." << std::endl;
#ifdef LOG
std::cout << "ip : " << _ip << std::endl;
std::cout << "port: " << _port << std::endl;
#endif
std::cout << "Init OK!" << std::endl;
}
//else code
private:
std::string _ip;
uint16_t _port;
//else code
};
int main(int argc, char* argv[]) {
Server *pserver;
if(argc != 1) {
pserver = new Server(argv[1], atoi(argv[2]));
}else{
pserver = new Server;
}
return 0;
}
編譯:
g++ test.cc -o test -std=c++11
運行結果:
- 使用默認值
- 不使用默認值
如果用上gflags,請看二。
二、如何在代碼中使用
還是上面那個情景,如果用gflags可以這麼寫:
//test2.cc
#include <iostream>
#include <string>
#include <gflags/gflags.h> //gflags庫的頭文件
//else header file
#define LOG
DEFINE_string(ip, "127.0.0.1", "IP address");
DEFINE_int32(port, 8080, "port");
class Server{
public:
Server(const std::string& ip, uint16_t port) : _ip(ip), _port(port) {
std::cout << "Init Server..." << std::endl;
#ifdef LOG
std::cout << "ip : " << _ip << std::endl;
std::cout << "port: " << _port << std::endl;
#endif
std::cout << "Init OK!" << std::endl;
}
//else code
private:
std::string _ip;
uint16_t _port;
//else code
};
int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
Server* pserver = new Server(FLAGS_ip, FLAGS_port);
return 0;
}
編譯:
g++ test2.cc -o test2 -lgflags -lpthread
注:爲什麼這麼編譯?請看三。
運行結果:
- 使用默認值
- 不使用默認值
相信經過上面那個demo後,讀者已經大致明白了這個庫怎麼用,我最後簡單的說明幾點:
-
使用前要先定義要使用的參數
例如前面代碼中的DEFINE_string(ip, "127.0.0.1", "IP address");
,這個宏的三個參數分別是:要使用的參數名,參數的默認值,參數的說明。gflags支持以下參數類型:- DEFINE_bool: bool
- DEFINE_int32: 32-bit integer
- DEFINE_int64: 64-bit integer
- DEFINE_uint64: unsigned 64-bit integer
- DEFINE_double: double
- DEFINE_string: C++ string
-
使用參數在參數名前加上
FLAGS_
例如前面代碼中的FLAGS_ip
。 -
在main函數開始時要初始化gflags
例如前面代碼中的gflags::ParseCommandLineFlags(&argc, &argv, true);
。
三、如何編譯使用gflags的代碼
在編譯的時候要加上-lgflags
和-lpthread
,因爲gflags內部是需要POSIX線程庫支持的,所以還需要加上-lpthread
。
除了這兩個外,也需要指定你安裝的gflags的庫文件(gcc選項:-L
)和頭文件(gcc選項:-I
)。由於我把這兩個放到了系統默認尋找的路徑,所以在編譯的時候沒有顯式指定。