c - 通过在 C 中读取 Command_Line 来更改项目的配置
问题描述
这可能是一个愚蠢的问题,但我可以问我如何通过阅读命令行来更改我的 C 项目配置?
例如,我的 C 项目由几个不同的文件组成。而我main()
解析命令行的方法是在a.c
. 配置,例如,使用多少个线程,命名为num_thread
,默认定义为宏,并且能够在使用 cmakelist 的编译中更改,在b.c
. 虽然它们位于不同的文件夹中。b
但是,的头文件b.h
是可见的a.c
。
我可以指出一些值得注意的事情吗?
- 首先,读取和解析命令行的函数,即
main()
,位于宏定义 (num_threads
) 所在的不同文件中并被使用。 - 其次,当我调用使用这些宏定义 ( ) 的函数时,我可以保存从命令行读取的那些值并将它们视为参数(参数
num_threads
)。如果我有那个特定的新值,我会替换那些宏。这在一些简单的项目中是可行的。但是我很遗憾地说我的项目太大了,我有很多层来传递那个单一的论点。所以这个方法在这里是行不通的。 - 第三,我的项目涉及多个线程,所以根本不应该使用全局变量。因为全局变量在多线程项目中是不安全的。
- 第四,我想到了一个解决方案,我定义了一个
static variable
inb.c
,并且有一个getter()
andsetter()
。每当我在 中读取新定义的配置时main()
,我都会调用setter()
它来设置static
. 每当我使用那个变量时,我都会打电话getter()
来看看我是否有一个新读取的变量。但我不认为这种方法很优雅,因为它static
有点像一个全局变量,甚至对它b.c
自己来说也是如此。
那么,有没有办法通过读取命令行参数来改变这样的配置?我知道在运行时更改宏定义是行不通的。因为宏是由预处理器处理并在编译中完成的。但是有没有办法做到这一点?提前致谢。
解决方案
通常有四种类型的“配置”:
编译时配置,通过将代码中的变量初始化为固定的编译时常量来设置的默认值。
就像您
num_threads
使用宏进行初始化一样。从文件中读取的配置。并非所有程序都需要这个。从文件中读取的配置会覆盖编译时配置。
在您的情况下,可能是您从某个文件中读取了一个数字,然后将该数字分配给
num_threads
.命令行参数。这就是你想知道的。
对于您的情况,您需要找出对应的参数
num_threads
,并将值分配给变量。运行时配置。可能不适用于您的情况,但运行时可能会发生导致某些配置值更改的事件。这又是一个简单的任务。
配置顺序如表所示,每增加一个杠杆,优先级就递增。并且这种优先级是上述系统中内置的,因为稍后的配置方法会分配或重新分配给变量,从而覆盖先前的值。
对于一个非常简单的示例,假设您只有编译时和参数配置选项。那么可能是这样的:
#define DEFAULT_NUM_THREADS 4
int main(int argc, char *argv[])
{
unsigned num_threads = DEFAULT_NUM_THREADS; // The compile-time configuration
if (argc == 2)
{
// Have one argument, this is the new number of threads
num_threads = strtol(argv[1], NULL, 10); // Argument configuration
}
// Use num_threads here...
}
如果没有传递给程序的参数,该num_thread
变量将保留其默认的编译时“配置”值。
推荐阅读
- asp.net-core - 升级到 aspnet core 3.1 后注销时出现 TypeLoadException 异常
- python - 如何在 django-import-export 中导入 django-taggit 标签
- javascript - 在 v-for 列表中显示元素:VueJS
- flutter - 防止键盘出现在 Flutter 上
- c - 如何在 ARM926EJ-S 上实现 SVC 处理程序?
- swift - becomeFirstResponder 直到至少触摸任何 UITextField 一次才显示键盘
- modelica - 在 Dymola 中使用可扩展连接器构建控制总线
- spring - 如果我从字段/构造函数注入中删除 @Autowired 但将该 bean 注入另一个类会发生什么
- javascript - 单击外部角度分量
- node.js - 需要建议在 mongodb 中使用 mongoose 设计数据库