簡體   English   中英

用嵌套結構數組初始化結構

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM