[英]Struct initialization with array of nested structs
我正在尝试使用结构创建文本解析状态机。 对于我用来测试它的较小结构,它似乎可以正常工作,但最终应用程序(调制解调器控制)所需的较大支柱似乎并没有像我在内存中那样被表示。
我认为问题在于初始化此结构:
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
足够的参数传递给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, ""))
};
当我们讨论这个主题时,强烈建议您删除这些宏。 他们什么都没有提供,但是当无法解释编译器错误消息时,就会引起堆栈溢出问题。 我建议像对states[0]
一样初始化每个变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.