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

2024-01-18

如何用C实现动态调度表 https://stackoverflow.com/questions/11840651/how-can-i-implement-a-dynamic-dispatch-table-in-c/32192330#32192330

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

因为您的 Strategy.c 显然已经知道该策略 按名称的实例 (#include "XYstrategy.h")你可以走整个 mile并使用头文件而不是实现文件来 将您的策略​​传达给中央调度员:

这与问题中明确的意图相悖。这是他如何静态执行此操作的示例,但希望模块在编译时动态注册自身。

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

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

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

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

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

The sensor_startup该功能将负责为传感器供电,确保它们配置正确并处于准备状态read_sensor被称为。如果此过程因任何原因失败,它将返回false,否则返回true.

The read_sensor函数将导致最多max_count要读取的传感器及其结果存储在指向的数组中temp and humidity, 分别。读取的传感器数量将存储在count.

The 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 中定义,反映可以选择的驱动程序的最大可能数量)。

这可能吗?如果是这样,有人可以提供语法示例吗?在这种特定情况下,我在粒子开发环境中为粒子光子进行编码,但如果我能让代码也可移植到 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

driver.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;

main.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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 语言混合:模型和视图

    考虑开发一个应用程序 其中模型将使用 C 使用 Boost 编写 视图将使用 Objective C 使用 Cocoa Touch 编写 哪里有一些示例展示了如何集成 C 和 Objective C 来开发 iPhone 应用程序 直接从源
  • 此插件导致 Outlook 启动缓慢

    我正在使用 C NET 4 5 开发 Outlook Addin 项目 但部署后 有时 Outlook 会禁用我的插件 并显示此消息 这个插件导致 Outlook 启动缓慢 我不知道我的插件出了什么问题 这只有很少的代码 并且ThisAdd
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • 隐形打开的弹出窗口

    第二天就解决这个问题 要重现 请创建新的 WPF 应用程序 xaml
  • C++ 模板参数类型推断

    我有一个这样的C 模板 template
  • Type_traits *_v 变量模板实用程序顺序无法编译

    看过了这个答案 https stackoverflow com a 31763111 7151494 我试图想出一个变量模板从中获取代码的实用程序 template
  • 使用正则表达式匹配以“Id”结尾的单词?

    如何组合一个正则表达式来匹配以 Id 结尾的单词并进行区分大小写的匹配 试试这个正则表达式 w Id b w 允许前面的单词字符Id和 b确保Id位于单词末尾 b是字边界断言
  • IBM Watson 对话服务错误:无法从“方法组”转换为“conversation.onMessage”

    我正在尝试运行 IBM Watson会话服务团结和下面是代码片段 https github com watson developer cloud unity sdk conversation private Conversation m C
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • IEnumerable.比带中断的 for 循环更快吗?

    我们的代码打开表单时遇到了一些缓慢的情况 这可能是由于for循环与break这需要很长时间才能执行 我把它切换到IEnumerable Any 并看到表格很快打开 我现在试图弄清楚是否单独进行此更改会提高性能 或者是否正在访问Product
  • 语义问题 Qt Creator:命名空间“std”中没有名为“cout”的成员

    我开始使用 Qt Creator 编写代码 对于 C 文件 我遇到很多语义问题 99 是 命名空间 yyy 中没有名为 xxx 的成员cpp文件构建 编译和输出没有问题 如果我点击例如cout 我已链接到 iostream 我是否需要在 Q
  • fscanf 和 EOF 中的否定扫描集

    我的文件中有一个以逗号分隔的字符串列表 姓名 1 姓名 2 姓名 3 我想跳过所有逗号来阅读这些名字 我写了以下循环 while true if fscanf file my string 1 break 然而 它总是比预期多执行一次 给定
  • 如何使用eclipse构建C++应用程序

    我已经从以下位置下载了 Eclipse Juno for C here http www eclipse org downloads download php file technology epp downloads release ju
  • 使 C# 编译器相信执行将在成员返回后停止

    我认为目前这是不可能的 或者这是否是一个好主意 但这是我刚才正在考虑的事情 我使用 MSTest 对我的 C 项目进行单元测试 在我的一项测试中 我执行以下操作 MyClass instance try instance getValue
  • printf 参数不足

    我的问题是关于缺少参数的 printf 之后的行为 printf s blah blah d int integer was given as argument and not int written 我已经知道 如果格式参数不足 则行为是
  • 获取大于某个数字的元素个数

    我正在尝试解决以下问题 数字被插入到容器中 每次插入数字时 我需要知道容器中有多少元素大于或等于当前插入的数字 我相信这两个操作都可以以对数复杂度完成 我的问题 C 库中有标准容器可以解决这个问题吗 我知道std multiset可以在对数
  • C 中的静态和动态绑定(严格来说是 C,而不是 C++)是什么?

    我最初对发布这个问题感到担忧 以免它重复 但即使在谷歌搜索了许多关键字之后 我在 StackOverflow 上找不到任何解释 C 的静态和动态绑定的链接 尽管有 C 的问题和答案 但是都涉及classes以及显然不适合 C 的东西 Sta
  • 计算两个日期之间的工作日数?

    在C 中 如何计算business 或工作日 两个日期之间的天数 我以前曾经遇到过这样的任务 并且我已经找到了解决方案 当可以避免的时候 我会避免列举其间的所有日子 这里就是这种情况 正如我在上面的一个答案中看到的那样 我什至没有提到创建一
  • C# 中成员访问中的问号是什么意思?

    有人可以向我解释一下以下代码中会员访问中的问号是什么意思吗 它是标准 C 的一部分吗 尝试在 Xamarin Studio 中编译此文件时出现解析错误 this AnalyzerLoadFailed Invoke this new Anal
  • XmlDocument Save 使文件保持打开状态

    我有一个简单的 C 函数 可以创建一个基本的 XML 文件并保存 private void CreateXMlFile string Filename string Name string Company XmlDocument doc n

随机推荐