0

初期化する構造体がいくつかありますが、手動で行うのは面倒です。私はそれに役立つマクロを作成したいと思っています... しかし、Cプリプロセッサがこれに十分であるかどうかはわかりません。

メニューを表す構造体があります。それらは関数ポインターのみで構成されています。

typedef uint8_t (*button_handler) (uint8_t);
typedef void (*pedal_handler) (void);
typedef void (*display_handler) (void);
typedef void (*menu_switch_handler) (void);

#define ON_BUTTON(x) uint8_t menu_frame_##x##_button (uint8_t button)
#define ON_PEDAL(x) void menu_frame_##x##_pedal (void)
#define ON_DISPLAY(x) void menu_frame_##x##_display (void)
#define ON_SWITCH(x) void menu_frame_##x##_switch (void)

typedef struct menu_frame {
   button_handler on_button;
   pedal_handler on_pedal;
   display_handler on_display;
   menu_switch_handler on_switch;
} menu_frame;

これにより、関数と個別の関数を (.c ファイル) として記述できます。

ON_BUTTON(blah) { ... }

およびメニューとして (.h ファイル):

ON_BUTTON(blah);
ON_DISPLAY(blah);
menu_frame menu_frame_blah = {
   menu_frame_blah_button,
   NULL,
   menu_frame_blah_display,
   NULL
};

メニュー定義を 1 つの定義に折りたたむ方法はありますか? MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL)もちろん、拡張することもできますが、次の方法はありますか?

  • 短くする(NULLまたは何らかの名前)
  • ON_BUTTON(...);構造体の前の fromの必要性を取り除く

MENU(blah, button, NULL, display, NULL)理想的には、ハンドラーとメニュー構造自体の両方を定義したいと思います。たとえば、最後の項が に展開されないようにする方法がわかりませんON_SWITCH(NULL)

それとも、別の方法でアプローチする必要がありますか?

4

3 に答える 3

1

以前、この種のコードを生成する Python スクリプトを作成したことがあります。そのルートに進み、スクリプトをビルド プロセスに組み込むこともできます。

于 2010-07-15T20:34:28.523 に答える
0

プリプロセッサだけで、条件分岐、有限ループ、デフォルト引数などすべてをプログラムできます。Boost ライブラリには、その一部がプリプロセッサ セクションに実装されています。Boost は主に C++ 用ですが、プリプロセッサは基本的に C でも動作するはずです。

このような手法を使用すると、複雑なマクロを作成できますが、使用は簡単です。C89 の代わりに C99 を使用すると、実装が少し簡単になります (初期化子とVA_ARGSに名前を付けました)。

于 2010-07-15T22:08:02.767 に答える
0

C では条件付きマクロ展開を行うことができないため、次のように引数に応じてマクロが異なる方法で展開されます。マクロ定義内で #if を使用することはできません。

あなたが得ることができる最高のものは のようなものだMENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL)と思いますが、条件付き展開がないため、プロトタイプ用に別のセットが必要です。

個人的には、その種のボイラープレート C コードを生成するための簡単なスクリプトを作成します。あなたの望む構文を理解するもの。Python またはあなたに最も適したもので…</p>

于 2010-07-15T20:26:48.887 に答える