看完都没时间总结下来,得空记录一点是一点吧。
在TAppDecoder工程中,source文件decmain.cpp main函数有两个参数int main(int argc,char* argv[]),一个是整型参数,一个是字符数组,这两个实参是什么,从何而来呢?这个小短篇简单给大家说明下,我们知道一个c或者c++的进程开始是从main()函数开始的,所以在开始前我们要给这个工程设置一些参数。
在Visual studio 2015中,我们右键点击TAppDecoder,选择属性->左边选择调试,然后在命令参数行设置如下-b str.bin -o my.yuv参数。
图1
那我给大家验证下这两个参数分别是什么,你可以选择自己在main()函数打印到显示屏幕上,如下图2:
图2
生成->运行的结果显示如下,从图3,我们发现argc是5,argv[0]我们这个字符数组第1个值是这个工程的可执行文件以及它所在的路径构成的字符数组,argv[1]-argv[4]是第2-5参数分别是在图1命令参数行输入的参数,第6个参数我故意打出来先告诉大家,它已经超出了这个字符数组的长度,故打出的值为null。
图3
当我们分析出main()函数的实参后,再去看源代码就简单了一些。
main()函数中我们遇到的第一个函数是create(),其实这个函数是没有什么实际功能意义的。
TAppDecTop cTAppDecTop;
// create application decoder class
cTAppDecTop.create();
它就是打印了一句”Add Debug point”
Void TAppDecTop::create()
{
fprintf(stdout, "Add Debug point");
}
我们再看对configuration的解析
if(!cTAppDecTop.parseCfg( argc, argv ))
{
cTAppDecTop.destroy();
returnCode = EXIT_FAILURE;
return returnCode;
}
它是TAppDecCfg类的函数,输入参数就是main()函数出传递进来的,返回值是Bool(typedef bool Bool)
Bool TAppDecCfg::parseCfg( Int argc, TChar* argv[] )
opts是命空间program_options_lite下面的一个结构体,该结构体里面声明了一个OptionSpecific lei类对象
class OptionSpecific;
struct Options
{
~Options();
OptionSpecific addOptions();
struct Names
{
Names() : opt(0) {};
~Names()
{
if (opt)
{
delete opt;
}
}
std::list
std::list
OptionBase* opt;
};
opts.addOptions()
定义了一个函数模板,重载了”()”运算符,在重载的运算符里面调用了addOption函数
template
OptionSpecific&
operator()(const std::string& name, T& storage, T default_val, const std::string& desc = "")
{
parent.addOption(new Option
return *this;
}
该函数的定义如下,所以上述代码在传参的时候需要传一个new后的对象
void addOption(OptionBase *opt);
这样在TAppDecCfg.cpp中opts.addOptions push多组实参用来解析配置参数和文件。
下面scanArgv函数判断各个参数是否满足-b ** -o **的格式。
scanArgv(Options& opts, unsigned argc, const char* argv[], ErrorReporter& error_reporter)
{
ArgvParser avp(opts, error_reporter);
/* a list for anything that didn't get handled as an option */
list
for(unsigned i = 1; i < argc; i++)
{
if (argv[i][0] != '-')
{
non_option_arguments.push_back(argv[i]);
continue;
}
if (argv[i][1] == 0)
{
/* a lone single dash is an argument (usually signifying stdin) */
non_option_arguments.push_back(argv[i]);
continue;
}
if (argv[i][1] != '-')
{
/* handle short (single dash) options */
i += avp.parseSHORT(argc - i, &argv[i]);
continue;
}
if (argv[i][2] == 0)
{
/* a lone double dash ends option processing */
while (++i < argc)
{
non_option_arguments.push_back(argv[i]);
}
break;
}
/* handle long (double dash) options */
i += avp.parseGNU(argc - i, &argv[i]);
}
return non_option_arguments;
}