C 定义为常量的数组成员

C 定义为常量的数组成员,c,frameworks,initialization,header-files,C,Frameworks,Initialization,Header Files,我正在尝试实现一个框架,在这个框架中,我需要声明(在.h文件中)在特定的.c模块中定义的可用“驱动程序”(结构变量)列表。由于该列表将来可能会增加,我希望将其全部放在.h文件中的一个位置,以使其易于扩展 例如,让我们来点“driver.h” 然后在专用模块中定义特定的驱动程序(驱动程序1、驱动程序2、驱动程序3)。。e、 g.驱动器1.c,驱动器2.c。。等等 但是,我希望有一个模块,例如manager.c,我想在其中定义driver.h中声明的可用驱动程序数组,这样我就能够迭代该数组,并获得在

我正在尝试实现一个框架,在这个框架中,我需要声明(在.h文件中)在特定的.c模块中定义的可用“驱动程序”(结构变量)列表。由于该列表将来可能会增加,我希望将其全部放在.h文件中的一个位置,以使其易于扩展

例如,让我们来点“driver.h”

然后在专用模块中定义特定的驱动程序(驱动程序1、驱动程序2、驱动程序3)。。e、 g.驱动器1.c,驱动器2.c。。等等

但是,我希望有一个模块,例如manager.c,我想在其中定义driver.h中声明的可用驱动程序数组,这样我就能够迭代该数组,并获得在框架的其他部分使用的驱动程序

因此,在manager.c中,我需要如下内容:

driver_t drivers[MAX_DRIVERS] = {DRIVERS}
但显然它不是这样编译的。。 主要思想是,当我将来需要为其他驱动程序添加声明时,只编辑driver.h,然后在专用模块中实现它,而无需编辑例如manager.c或框架的其他部分。。
在C中,如何实现C?< /P >

中的这种机制,不能用一些对象的拷贝初始化数组(C++中的,但它不是好的实践,因为它们是副本,并且将与原始对象独立地改变)。

驱动程序
数组应包含指向原始对象的指针。我建议像

/*driver.h*/
typedef结构驱动程序{
int-id;
字符名[10];
int(*init)();
无效(*脱硝)();
int(*doTheJob)(int);
}司机;;
#定义最大驱动程序10
#定义DRIVERLIST driver1、driver2、driver3
#定义驱动程序\u INIT{&driver1,&driver2,&driver3}
#定义驱动程序外部驱动程序列表;
司机
/*manager.c*/
#包括“driver.h”
/* ... */
driver\u t*drivers[MAX\u drivers]=drivers\u INIT;

管理器代码将使用
drivers[i]->id
而不是
drivers[i].id

在C中执行此操作的正确方法是立即删除所有
extern
-带globals的意大利面

相反,您可以将结构定义放在
driver.h
中,并通过“构造函数”在
driver.c
中初始化它:


对于专业代码,这可以通过解释的“不透明类型”概念进一步改进,以实现私有封装(以及如果需要多态性)。在这种情况下,结构定义可以(部分)隐藏在driver.c中,构造函数还处理内存分配。

我想我找到了一个解决方案。我的灵感来自于rtl_433项目,在该项目中,他们为设备声明定义了类似的内容

所以它应该在头文件中:

/* driver.h */
#define DRIVERS \
    DECL(driver1) \
    DECL(driver2) 


#define DECL(name) extern driver_t name;
    DRIVERS
#undef DECL
然后在模块中:

/* driver.c */

driver_t* drivers[] = {  
#define DECL(name) &name,
    DRIVERS
#undef DECL
};

driver\u t drivers[MAX\u drivers]={DRIVERSLIST}@ReAl它也不会以这种方式编译:(请添加编译器错误消息。代码在哪里?Max驱动程序< /COD> DeFEN?@真。错误:初始化器元素不是常数,Max驱动程序是在驱动程序中定义的。H定义了Max驱动程序10,但是它运行良好,问题是在Manager C中的实际数组定义。谢谢。哦,是的,代码<不是常数< /代码>!对不起,它是C,不是C++。等一下。谢谢,编译的很好。使用这个解决方案很有诱惑力,但是如果能够在一个地方声明驱动程序名称就太好了。根据你的建议,当我需要额外的驱动程序时,我需要在DRIVERLIST和DRIVERS_INIT中添加它。这不是什么大问题,但是……无论如何,非常感谢!谢谢。但是……构造函数会如何呢看起来好像有10个或更多的驱动程序?每个驱动程序模块都需要有唯一的函数名?添加新的驱动程序会很麻烦,不是吗?我明白你的意思。我也不喜欢奇怪的宏和声明,但在这种情况下,通过添加一个在统一专用模块IMHO..@pedroke中尝试单位置及其实现,您可以实现某种多态性,也可以简单地将细节留给特定的驱动程序是某种形式的接口/抽象基类-否则您的设计就没有任何意义。对象的分配是一个单独的问题。这称为“x宏”在其他一切都失败的情况下,这真的是最后的手段。将它们与通心粉球结合起来不是一个好主意。在我看来,这似乎是C在这种情况下提供的可能性的最后手段。我没有找到任何其他方法来声明“可插拔”模块,比如我的例子中的驱动程序。当项目有多个贡献者,并且任何人都可以实现额外的驱动程序时,在单个位置维护驱动程序会容易得多,并且不需要教新的贡献者在哪里以及如何在不同的位置扩展代码。任何人都可以实现具有驱动程序行为的专用模块然后在头文件中添加一行。。
/* driver.h */
#define DRIVERS \
    DECL(driver1) \
    DECL(driver2) 


#define DECL(name) extern driver_t name;
    DRIVERS
#undef DECL
/* driver.c */

driver_t* drivers[] = {  
#define DECL(name) &name,
    DRIVERS
#undef DECL
};