3

如何在 C 中实现动态调度表

这与链接问题本质上是相同的问题,所以......

由于您的 Strategy.c 显然已经通过名称 ( ) 知道策略实例,#include "XYstrategy.h"您可以全力以赴并使用头文件而不是实现文件将您的策略​​传达给中央调度程序:

这与问题中的明确意图相反。这是他如何静态完成的示例,但希望模块在编译时动态注册自己。

让我尝试提供一个我为自己的目的而苦苦挣扎的例子......

我有一个微控制器,我想用它来读取各种报告温度和/或湿度的传感器。我有一个中央核心程序,负责格式化返回的数据并将其提交到记录在 RRD 中的 Web 服务器。

我不想构建一个包含每种传感器类型的所有不同功能的大型单片程序,而是希望能够将特定子集构建到加载到微控制器上的软件中,该软件与安装在该特定控制器上的传感器相对应。

为此,我希望能够为具有三个功能的每个传感器编写一个通用驱动程序:

bool _sensor_startup();
bool _read_sensor(float *temp, float *humidity, uint8_t max_count, uint8_t *count);
bool _sensor_shutdown();

sensor_startup函数将负责启动传感器,确保它们已正确配置并处于准备好read_sensor调用的状态。如果此过程因任何原因失败,则返回false,否则返回true

read_sensor函数将导致最多读取传感器,其结果分别存储在和max_count指向的数组中。读取的传感器数量将存储在.temphumiditycount

sensor_shutdown功能将执行任何必要的内务处理,以将传感器和支持电子设备恢复到最低功耗配置。

这些中的每一个都包含在一个单独的 .c 文件中,该文件可能有一个相应的 .h 文件来定义相关常量、调用相关库等。

我想要一个包含在 .c 或 .h 文件中的主 Sensor.h 文件,它定义:

typedef struct { startup_func, read_func, shutdown_func } sensor_driver_entry;

extern sensor_driver_entry sensor_table[];

然后我希望每个驱动程序文件都能够使用宏(或函数)在编译时在 sensor_table 的下一个开放槽中注册特定于类型的函数。

我希望在 Sensor.c 的全局命名空间中将传感器表声明为:

sensor_driver_entry sensor_table[MAX_SENSOR_TYPES];

MAX_SENSOR_TYPES将在 Sensor.h 中定义,反映可以选择的最大驱动程序数量)。

这甚至可能吗?如果是这样,有人可以提供一个句法示例吗?在这种特定情况下,我在 Particle Dev 环境中为 Particle Photon 进行编码,但如果我可以使代码也可移植到 Arduino IDE 以将其与 ESP8266 板一起使用,我会很高兴。

4

1 回答 1

2

一种可能性是使用构造函数。下面是一个简单的例子,两个驱动程序分别注册它们的功能。

如果应用程序使用两个驱动程序 ( gcc main.c driver1.c driver2.c) 编译,则输出显示两个驱动程序函数都已注册:

driver1_init
driver2_init
driver1_func
driver2_func

如果仅在 ( gcc main.c driver1.c) 中编译了第一个驱动程序,则输出仅显示已注册该驱动程序的函数:

driver1_init
driver1_func

驱动程序.h

typedef void (*driver_func_t)(void);
typedef struct { driver_func_t func; } driver_entry_t;

#define MAX_TYPES 10
extern driver_entry_t driver_table[MAX_TYPES];
extern unsigned int num_driver_entries;

主程序

#include <stdio.h>
#include "driver.h"

driver_entry_t driver_table[MAX_TYPES];
unsigned int num_driver_entries;

int main (void)
{
    unsigned int ix;

    for (ix = 0; ix < num_driver_entries; ix++) {
        driver_table[ix].func();
    }

    return 0;
}

驱动程序1.c

#include <stdio.h>
#include "driver.h"

void driver1_func (void)
{
    printf("%s\n", __FUNCTION__);
}

void driver1_init (void) __attribute__ ((constructor));
void driver1_init (void)
{
    printf("%s\n", __FUNCTION__);
    driver_table[num_driver_entries++].func = driver1_func;
}

驱动程序2.c

#include <stdio.h>
#include "driver.h"

void driver2_func (void)
{
    printf("%s\n", __FUNCTION__);
}

void driver2_init (void) __attribute__ ((constructor));
void driver2_init (void)
{
    printf("%s\n", __FUNCTION__);
    driver_table[num_driver_entries++].func = driver2_func;
}
于 2015-08-25T05:14:26.960 回答