gpt4 book ai didi

GCC 中的 CLI 命令表

转载 作者:太空宇宙 更新时间:2023-11-03 23:52:08 25 4
gpt4 key购买 nike

我的 AVR 微 Controller 固件中有一个简单的命令行界面,它基于如下结构:

typedef struct {
const char *name;
const char *usage;
const char *help;
void (*handler)(char **last);
} command_t;

extern command_t *cli_commands[];

我希望能够以尽可能干的方式在不同的模块中声明命令。到目前为止,我已经有了它,所以我可以这样定义我的函数:

COMMAND_IMPL(replay, "replay <n>", "Replay frame n") {
// 'last' argument is for strtok_t
}

然后我必须将其放入我的一个 .c 文件中:

COMMAND_DECL(list);
COMMAND_DECL(clear);
COMMAND_DECL(replay);

COMMAND_TABLE
COMMAND(list)
COMMAND(clear)
COMMAND(replay)
END_COMMAND_TABLE

我的宏是这样的:

#define COMMAND_IMPL(name, usage, help) \
static void cli_handle_##name##_command(char **);\
command_t cli_##name##_command = {#name, usage, help, cli_handle_##name##_command};\
static void cli_handle_##name##_command(char **last)
#define COMMAND_DECL(name) extern command_t cli_##name##_command;
#define COMMAND_TABLE command_t *cli_commands[] = {
#define COMMAND(name) ((command_t *) &cli_##name##_command),
#define END_COMMAND_TABLE NULL };

还能做得更好吗?该项目已经绑定(bind)到 avr-gcc,所以我不介意它是否是一个仅限 GCC 的解决方案。使用链接器功能的解决方案也可以(我正在编译为 ELF)。我在想也许我可以将命令条目放在不同的部分,并将其链接到某个已知的地方,但我想不出它会如何终止。

最佳答案

您可以像这样使用 section 属性(这是 linux 内核导出其函数的方式):

#define COMMAND_IMPL(name, usage, help) \
static void cli_handle_##name##_command(char **); \
command_t cli_##name##_command __attribute((section("commands"))) = { #name, usage, help, cli_handle_##name##_command }; \
static void cli_handle_##name##_command(char **last)

然后,您可以使用 ld 脚本(参见 http://www.math.utah.edu/docs/info/ld_3.html )获取“命令”部分开始/结束的地址:

...
SECTION commands ALIGN(4) : {
commands_begin = .;
*(commands)
commands_end = .;
}

最后声明两个变量:

extern command_t commands_begin, commands_end;

然后您可以使用这些变量的地址来获取整个命令结构列表,即

for (command_t *cmd = &commands_begin; cmd != &commands_end; cmd++)
...

注意 &commands_end 是如何指向最后一条命令之后的。

关于GCC 中的 CLI 命令表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17314277/

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