gpt4 book ai didi

在 C 中跨多个源文件创建调度表注册函数

转载 作者:行者123 更新时间:2023-12-04 12:07:02 25 4
gpt4 key购买 nike

How can I implement a dynamic dispatch table in C

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

As your Strategy.c obviously already knows about the strategy instances by name (#include "XYstrategy.h") you could go the whole mile and use the header files instead of the implementation files to communicate your strategy to the central dispatcher:

这与问题中的明确意图背道而驰。这是一个示例,说明他如何静态地执行此操作,但希望让模块在编译时动态注册自己。

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

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

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

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

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 个传感器,并将它们的结果存储在 temp 指向的数组中>湿度,分别。读取的传感器数量将存储在count中。

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

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

我想要一个主 Sensor.h 文件,它包含在 .c 或 .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 中定义,反射(reflect)可以选择的驱动程序的最大可能数量)。

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

最佳答案

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

如果应用程序是使用两个驱动程序编译的 (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;

主.c

#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;
}

关于在 C 中跨多个源文件创建调度表注册函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32195298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com