在不影响C或C ++应用程序的现有设计的情况下增加新职责

时间:2012-01-03 03:40:11

标签: c++ c

我要求组件负责接收消息和 处理消息。应该有一个通用的消息接口,例如uint8数组(它是一个二进制消息)和一个通用框架,从外部配置文件读取,一个处理程序列表。处理程序应实现通用接口,例如: -

uint8[] process(uint8[] message);

每个处理程序都应处理消息并将处理后的消息返回给框架,以便框架可以将处理后的消息传递给下一个处理程序,依此类推。 这种方法的优点在于它可以通过在配置文件中添加新的处理程序来允许在运行时添加新功能。通用框架应该初始化新的处理程序,将它放在处理程序的相应位置,并通过所有处理程序传递消息。

我已经在Java中多次实现了这种方法,但我很难在C和C ++中实现它。例如在C中,我想也许通过一个指向框架的函数指针来注册每个处理程序的进程函数,这样框架就可以将消息传递给每个处理程序。但我不知道如何基于配置文件初始化处理程序。配置文件将包含处理程序的“String”名称。 main方法如何将该字符串名称映射到处理程序文件?

任何指向存在这种模式的代码的指针都会非常有用。

2 个答案:

答案 0 :(得分:2)

对于C,你有几个选择。

一种是使用dlsym()或其等价物来查找与指定为字符串的函数名称对应的函数指针。

另一种是使用预定的名称数组和相应的函数指针。如果接口变化,这会变得混乱(尽管dlsym()也存在问题)。

struct func_name
{
    const char *name;
    uint8   (*function)(void);
};

static const struct func_name func_list[] =
{
    { "function1",       function1       },
    { "anotherfunction", anotherfunction },
};

然后,您可以使用搜索(如果按顺序保留名称,可能是二进制搜索,与我的示例不同),以查找与名称对应的函数指针。与dlsym()查找相比,此技术的一个优点是数组中的名称不需要与函数名称匹配,因此如果有意义,您可以提供别名。

答案 1 :(得分:2)

如果您的配置文件说明了这一点:

handler1.so
handler2.so
handler3.so

你在Linux平台上,你可以这样做:

void *lib = dlopen(name, RTLD_NOW);
typedef uint8* (handler_t)(uint8*);
handler_t *func = (handler_t*)dlsym("handler");

为配置文件中的每个名称。这会动态加载一个共享库,每个库都包含一个处理函数(名为“handler”)。

对于其他操作系统,存在类似的工具(Windows上的LoadLibrary,例如* .dll)。