gpt4 book ai didi

c - 使用嵌套结构数组进行结构初始化

转载 作者:太空宇宙 更新时间:2023-11-04 03:43:12 24 4
gpt4 key购买 nike

我正在尝试使用结构创建文本解析状态机。它似乎适用于我用来测试它的较小结构,但我的最终应用程序(调制解调器控制)所需的较大支柱似乎没有像我希望的那样在内存中表示。

我认为问题在于初始化这个结构:

struct state
{
size_t const id;
size_t(* const callback)(void*);
void* const callback_arg;
char const* const out_pattern;
size_t const out_pattern_length;
unsigned long int timeout;
size_t const timeout_state;
size_t const next_states_length;
struct next_state const* next_states;
};

使用这个宏:

#define sm_state(id, callback, callback_arg, out_str, out_str_length, timeout, \
timeout_state, next_states_length, ...) \
{id, callback, callback_arg, out_str, out_str_length, timeout, \
timeout_state, next_states_length, \
(struct next_state const[next_states_length]){__VA_ARGS__}}

next_state 在哪里:

#define sm_next_state(next_state_id, in_pattern_length, in_pattern) \
{next_state_id, in_pattern_length, in_pattern}

struct next_state
{
size_t const next_state;
size_t const in_pattern_length;
char const* in_pattern;
};

有效的测试用例是:

enum states_enum
{
fruit = 1,
vegitable,
error,
};

struct state const states[] = {
// id callback callback argument pattern to be sent on entry patlen timeout t/o state next states count next_states
sm_state( fruit, NULL, NULL, "hello, pick a fruit\n", 20, 100000UL, 1, 3, sm_next_state(fruit, 4, "pear"), sm_next_state(vegitable, 5, "apple"), sm_next_state(error, 6, "turnip")),
sm_state( vegitable, NULL, NULL, "now pick a vegetable\n", 21, 100000UL, 3, 3, sm_next_state(fruit, 7, "cabbage"), sm_next_state(vegitable, 6, "potato"), sm_next_state(error, 6, "turnip")),
sm_state( error, NULL, NULL, "error, you entered turnip...\n", 29, 100000UL, 1, 3, sm_next_state(fruit, 3, "one"), sm_next_state(vegitable, 3, "two"), sm_next_state(error, 6, "turnip"))
};

int i = 0;
while (i < 3)
{
printf("id: %d\n", states[i].id);
++i;
}

输出:

id: 1
id: 2
id: 3

还有更大的结构不起作用:

enum bluetooth_states_enum
{
bt_off = 1,
bt_on,
bt_set_echo_off,
bt_set_auto_answer,
bt_set_ignore_dsr,
bt_set_spp,
bt_set_io_cap,
bt_set_mitm_protection,
bt_write,
bt_reset,
bt_set_firendly_name,
bt_set_connectable,
bt_set_key,
bt_listening,
bt_answer,
bt_in_call,
bt_hup,
bt_error,
};

struct state const states[] = {
sm_state( bt_off, NULL, NULL, "", 0, -1, bt_off, 0,),
sm_state( bt_on, NULL, NULL, "AT\r", 3, 100000UL, bt_error, 2, sm_next_state(bt_set_echo_off, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_echo_off, NULL, NULL, "ATE0\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_set_auto_answer, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_auto_answer, NULL, NULL, "ATS0=2\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_ignore_dsr, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_ignore_dsr, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_spp, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_spp, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_io_cap, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_io_cap, NULL, NULL, "ATS321=0\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_mitm_protection, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_mitm_protection, NULL, NULL, "ATS322=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_write, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_write, NULL, NULL, "AT&W\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_reset, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_reset, NULL, NULL, "ATZ\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_set_firendly_name, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_firendly_name, NULL, NULL, "AT+BTF=\"Friendly Name\"\r", 18, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_connectable, NULL, NULL, "AT+BTP\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_key, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_key, NULL, NULL, "AT+BTK=\"8475\"\r", 14, 100000UL, bt_error, 2, sm_next_state(bt_listening, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_listening, NULL, NULL, "", 0, -1, 0, 1, sm_next_state(bt_answer, 4, "RING")),
sm_state( bt_answer, NULL, NULL, "ATA\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_in_call, 7, "CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_in_call, NULL, NULL, "", 0, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 10, "NO CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_error, NULL, NULL, "", 0, -1, bt_off, 1, sm_next_state(bt_off, 0, ""))
};

输出:

id: 1820602156
id: 7
id: -1
id: 1973037073
id: 0
id: 0
id: 123336558
id: 0
id: 0
id: 0
id: 736
id: 760826203
id: 3108
id: -1322777276
id: 1
id: 7916
id: 152

似乎内存中不存在更大的示例。如果有人能指出我做错了什么,那就太棒了。

最佳答案

所以看起来问题在于您没有在声明 states[0] 中向 sm_state 传递足够的参数。

如果你这样声明它会起作用:

struct state const states[] = {
{bt_off, NULL, NULL, "", 0, -1, bt_off, 0},
sm_state( bt_on, NULL, NULL, "AT\r", 3, 100000UL, bt_error, 2, sm_next_state(bt_set_echo_off, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_echo_off, NULL, NULL, "ATE0\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_set_auto_answer, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_auto_answer, NULL, NULL, "ATS0=2\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_ignore_dsr, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_ignore_dsr, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_spp, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_spp, NULL, NULL, "ATS102=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_io_cap, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_io_cap, NULL, NULL, "ATS321=0\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_set_mitm_protection, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_mitm_protection, NULL, NULL, "ATS322=1\r", 9, 100000UL, bt_error, 2, sm_next_state(bt_write, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_write, NULL, NULL, "AT&W\r", 5, 100000UL, bt_error, 2, sm_next_state(bt_reset, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_reset, NULL, NULL, "ATZ\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_set_firendly_name, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_firendly_name, NULL, NULL, "AT+BTF=\"Friendly Name\"\r", 18, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_connectable, NULL, NULL, "AT+BTP\r", 7, 100000UL, bt_error, 2, sm_next_state(bt_set_key, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_set_key, NULL, NULL, "AT+BTK=\"8475\"\r", 14, 100000UL, bt_error, 2, sm_next_state(bt_listening, 2, "OK"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_listening, NULL, NULL, "", 0, -1, 0, 1, sm_next_state(bt_answer, 4, "RING")),
sm_state( bt_answer, NULL, NULL, "ATA\r", 4, 100000UL, bt_error, 2, sm_next_state(bt_in_call, 7, "CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_in_call, NULL, NULL, "", 0, 100000UL, bt_error, 2, sm_next_state(bt_set_connectable, 10, "NO CONNECT"), sm_next_state(bt_error, 5, "ERROR")),
sm_state( bt_error, NULL, NULL, "", 0, -1, bt_off, 1, sm_next_state(bt_off, 0, ""))
};

当我们讨论这个主题时,我强烈建议您删除这些宏。当无法破译编译器错误消息时,它们只提供 stackoverflow 问题。我建议像使用 states[0] 一样初始化每个变量。

关于c - 使用嵌套结构数组进行结构初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26843114/

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