0

次のように、組み込みシステムにメニュー構造を作成しました。

struct DisplayMenu
{
    short int MenuTitle;                                        // Menu title text offset - the title used in the calling menu
    char NoOfSubmenuItems;                                      // number of submenuItems in this menu ? static!
    char PositionInLastMenu;                                    // position in previous menu - helps restore previous menu screen
    struct DisplayMenu *PreviousMenu;                           // pointer to previous menu - need to be const?
    struct DisplayMenu *NextMenu[MAX_NO_OF_SUBMENU_ITEMS];      // array of pointers to submenus structs - Null if no submenu...function call instead
    void (*MenuFunctionsArray[MAX_NO_OF_SUBMENU_ITEMS])(void);  // array of function pointers - called if no submenu. Check if null
    const short int *SubMenuText;                               // pointer array of text offsets for submenu text - no set length variable length array allowed at end of struct in GCC at least
};

初期のプロトタイピングのために次のようにインスタンス化されます。

const short int MainMenuTextStrings[]= { tSTATUS, tSETUP, tStartOfTextString, tANALYSER, tUNITS, tEndOfTextString, tUNITS, tALARM, tSCREEN, tREPORTS, tSERVICE, tStartOfTextString, tMANUAL, tAIR, tZERO, tEndOfTextString, tStartOfTextString, tMANUAL, tEndOfTextString, NULL };     // needs a new text entry

// main menu struct
struct DisplayMenu MainMenu =
{
    tMENU,                                                                                              // Menu title
    0,                                              // number of submenus
    0,                                                                                                  // no previous menu 
    NULL,                                                                                               // no previous menu to point to
    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },                                     // to be set up later
    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },                                     // function pointers
    MainMenuTextStrings
};

後で機能/メニューポインタなどを初期化する目的で

GCC で問題なくコンパイルできますが、コードが実行されているとき (動的ではないメニュー システムが既に稼働している場合)、IDE (MPLABX) は MainMenu の内容を表示するのに苦労し、関数 DisplayMenuItems を実行しようとすると (以下のように)私はそれを介してステップすることはできません

構造体を定義してインスタンス化した方法に問題があることを誰かが見つけることができますか?

構造体を使用してアイテムを表示するには、次の関数を使用する予定です。

void DisplayMenuItems(struct DisplayMenu* Menu)
{

    while(*(Menu->SubMenuText) != NULL)
    {
        if(*(Menu->SubMenuText) == tStartOfTextString)       //if a few text strings need to be concatenated on one line
        {
            while(*(Menu->SubMenuText++) != tEndOfTextString)  //keep printing until you find the EndofTextString ident
                WriteStringToDisplay((char*) &pText[Config.ucLanguage][*(Menu->SubMenuText)], SmallFont);
        }
        else /*if(*(Menu->SubMenuText) != NULL) */
        {
            WriteStringToDisplay((char*) &pText[Config.ucLanguage][*(Menu->SubMenuText)++], SmallFont);
        }
        DisplayCarriageReturn(2,SmallFont);         // try and remove this eventually? Just increment Lcd.ucLine instead
    }
}

GCC は、私がここで想定されていないことを回避できるようにする可能性があるため、ヒントをいただければ幸いです。

どうもありがとう

4

1 に答える 1

2

問題はおそらく、ループ内でポインターを変更していることです。つまり、DisplayMenuItems関数が 2 回目に呼び出されると、ポインターは配列を指しなくなりますが、MainMenuTextStrings配列を超えてそのデータにアクセスすると、未定義の動作が発生します。

ポインターを変更する代わりに、単純に配列インデックス構文を使用してみませんか?

お気に入り

for (unsigned int i = 0; Menu->SubMenuText[i] != NULL; ++i)
{
    ...
}
于 2014-08-06T11:47:45.443 に答える