我想同樣的功能。不幸的是我沒有在文檔中找到它。因此我攻擊了一個解決方案。基本上,我檢查第一個參數,驗證它並將其餘參數傳遞給模塊。每個模塊都定義了自己的選項。
#include <boost/program_options.hpp>
// ...
using namespace cv;
using namespace std;
namespace po = boost::program_options;
int signModule(int argc, char** argv);
int kfModule(int argc, char** argv);
int main(int argc, char** argv)
{
string helpText = "You need to specify a module:\n\tprogram [sign|kf]\n\nUse program <module> --help for a description.";
if (argc < 2) { // Then no module was given
cout << helpText << endl;
return -1;
}
string module = argv[1]; // This is the first argument. Index 0 holds the executable
// Copy argv but exclude argv[1}
int moduleArgC = argc -1;
char* moduleArgV[moduleArgC];
moduleArgV[0] = argv[0];
for(int i=1; i < moduleArgC ;++i) {
moduleArgV[i] = argv[i+1];
}
if (module == "sign")
return signModule(moduleArgC, moduleArgV);
else if (module == "kf")
return kfModule(moduleArgC, moduleArgV);
else { // default
cout << "Unknown module: " << module << "\n\n" << helpText << endl;
return -1;
}
}
int signModule(int argc, char** argv) {
try {
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("circle,c", po::value<string>(&recognizer::circleClassifierFilePath)->default_value(recognizer::circleClassifierFilePath), "Path to CircleClassifier")
("triangleUp,t", po::value<string>(&recognizer::triangleClassifierFilePath)->default_value(recognizer::triangleClassifierFilePath), "Path to TriangleUpClassifier")
("winSize,w", po::value<int>()->default_value(recognizer::winSize.width), "WinSize of HOGDescriptor as int")
("createHog", po::bool_switch(&recognizer::createHogFeaturesFromImages)->default_value(recognizer::createHogFeaturesFromImages), "Specifies if HOG features will be created even if HOG file is present.")
("svmKernel", po::value<int>(&recognizer::svmKernel)->default_value(recognizer::svmKernel), "The SVM kernel of the classifiers. LINEAR =0, POLY =1, RBF =2, SIGMOID =3, CHI2 =4, INTER =5")
("degree", po::value<double>(&recognizer::degreeOfPolyKernel)->default_value(recognizer::degreeOfPolyKernel), "The degree for the polynomial SVM kernel. Makes only sense with option --svmKernel=1 (POLY).")
;
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
options(desc).run(), vm);
po::notify(vm);
if (vm.count("help")) {
cout << "Usage: program [options]\n";
cout << desc;
return 0;
}
// Validate options
if (vm.count("winSize"))
{
int winSize = vm["winSize"].as<int>();
recognizer::winSize = Size(winSize, winSize);
}
if (vm["svmKernel"].as<int>() < 0 || 5 < vm["svmKernel"].as<int>()) {
cout << "Wrong svmKernel:\t" << vm["svmKernel"].as<int>() << "\tAllowed values: LINEAR =0, POLY =1, RBF =2, SIGMOID =3, CHI2 =4, INTER =5" << endl;
return 1;
}
}
catch(std::exception& e)
{
cout << e.what() << "\n";
return 1;
}
SignClassifier::createClassifier();
return 0;
}
int kfModule(int argc, char** argv) {
// Another module with different options
// ...
return 0;
}
另請參閱我的blog post。
感謝您的回覆。這對於某些場景似乎很有用,但我正在尋找的多模塊案例是模塊同時使用的地方。理想情況下,我想要一些架構,其中我依賴注入的每個具體類(模塊)都可以註冊自己的一組選項,並在配置文件中擁有自己的部分。 – Olympionex