Frage

Ich muss einige Strukturen initialisieren, was manuell mühsam wäre.Ich möchte ein Makro erstellen, das mir dabei hilft...aber ich bin mir nicht sicher, ob das C der Präprozessor ist dafür gut genug.

Ich habe Strukturen, die Menüs darstellen.Sie bestehen nur aus Funktionszeigern:

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;

Das erlaubt mir, die Funktionen und separaten Funktionen als ( .c-Datei):

ON_BUTTON(blah) { ... }

und Menüs als (.h-Datei):

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

Gibt es eine Möglichkeit, die Menüdefinition in eine Definition zu falten?Ich könnte etwas tun, das sich ausdehnt MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL) natürlich, aber gibt es einen Weg dazu:

  • machen Sie es kürzer (NULL oder ein Name)
  • entfernen Sie die Notwendigkeit von ON_BUTTON(...); von vor der Struktur

Idealerweise würde ich gerne MENU(blah, button, NULL, display, NULL) um sowohl die Handler als auch die Menüstruktur selbst zu definieren.Ich weiß zum Beispiel nicht, wie ich verhindern soll, dass der letzte Begriff in erweitert wird ON_SWITCH(NULL).

Oder sollte ich es vielleicht auf andere Weise angehen?

War es hilfreich?

Lösung

Sie können in C keine bedingte Makroerweiterung durchführen, sodass Ihr Makro je nach Argumenten unterschiedlich erweitert wird, wie in:sie können #if nicht innerhalb der Makrodefinition verwenden.

Ich denke, das Beste, was du bekommen könntest, wäre so etwas wie MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL), und Sie benötigen immer noch ein separates Set für Prototypen, da keine bedingte Erweiterung vorhanden ist.

Persönlich würde ich ein einfaches Skript schreiben, um diese Art von Standard-C-Code zu generieren.Eine, die Ihre gewünschte Syntax verstehen würde.In Python oder was auch immer Ihnen am besten passt…

Andere Tipps

Ich habe zuvor Python-Skripte geschrieben, um diese Art von Code für mich zu generieren.Vielleicht möchten Sie diesen Weg gehen und das Skript einfach in Ihren Erstellungsprozess einarbeiten.

Sie können Bedingungen, endliche Schleifen, Standardargumente und all diese Dinge nur im Präprozessor programmieren.Die Boost-Bibliothek hat eine Implementierung von einigen davon in ihrem Präprozessorabschnitt.Boost ist hauptsächlich für C ++ gedacht, aber das Präprozessor-Zeug sollte grundsätzlich auch in C funktionieren.

Mit solchen Techniken können Sie komplizierte Makros schreiben, die jedoch einfach zu verwenden sind.Es wird etwas einfacher zu implementieren, wenn Sie C99 anstelle von C89 verwenden (Sie haben Initialisierer benannt und VA_ARGS), aber trotzdem.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top