2010-07-15 53 views
0

我有一些結構初始化,這將是手動操作繁瑣。我想創建一個可以幫助我的宏...但是我不確定預處理器是否足夠滿足這個要求。通過宏過度使用結構初始化

我有代表菜單的結構。他們只包含一個函數指針:

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 
}; 

有沒有什麼辦法可以將菜單定義摺疊成一個定義?我可以做一些擴展,當然MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL),但有什麼辦法:

  • 把它縮短了(NULL或部分名稱)
  • 從結構

之前刪除的ON_BUTTON(...);需要理想情況下,我想MENU(blah, button, NULL, display, NULL)都定義處理程序和菜單結構本身。我不知道如何防止將最後一項擴展爲ON_SWITCH(NULL)

或者我應該從其他方式來處理它?

+0

你想寫一個C版本的MFC嗎? ;-) – 2010-07-15 20:17:10

+0

也許:)其實一些嵌入的東西與不同的菜單狀態加載(足夠寫很多行ON_BUTTON(some_other_state))。 – viraptor 2010-07-15 20:19:30

回答

0

您不能在C中進行條件宏擴展,以便您的宏將根據參數進行不同的擴展,如下所示:在宏定義中不能使用#if。

我想你能得到的最好的東西就像MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL),你仍然需要一個單獨的原型設置,因爲缺乏條件擴展。

就我個人而言,我會編寫一個簡單的腳本來生成這種樣板C代碼。一個會理解你想要的語法。在Python或任何適合你最好...

+0

我知道我不能在宏中做一個標準的條件語句,但是我真的在計算一些有趣的語法,如果它用NULL來擴展到一個NOOP,並且聲明它是其他東西,那麼它就會減少到一個NOOP ...但是 - 是不可能的。我會嘗試外部生成。 – viraptor 2010-07-15 20:30:20

+0

-1因爲我們的陳述是錯誤的。在Boost預處理器庫中,它們具有這些類型的條件宏,這些宏根據宏參數可以做不同的事情,例如BOOST_PP_EXPR_IF。 – 2010-07-17 21:11:06

+0

那麼它會做一個NULL檢查?因爲這裏的源代碼http://www.boost.org/doc/libs/1_41_0/boost/preprocessor/logical/bool.hpp表明它確實需要由預處理器評估的條件從0到256的數字。BOOST_PP_EXPR_IIF雖然是一件很聰明的事情。 – 2010-07-21 12:42:30

1

我寫了Python腳本來爲我生成這種類型的代碼之前。您可能想要走這條路線,並將腳本運用到您的構建過程中。

0

您可以在預處理器中編寫條件,有限循環,默認參數和所有這些東西。 Boost庫在它們的預處理器部分中有一些實現。 Boost主要用於C++,但預處理器的東西基本上也應該用C語言編寫。

通過這種技術,您可以編寫複雜的宏,但使用起來很簡單。當使用C99而不是C89時(實際上你已經命名了初始值設定項和VA_ARGS),但實現起來會更簡單。

+0

任何特別的原因downvote? (目前+1 -2) – 2010-07-16 16:45:04

+0

我低估了,因爲你沒有任何例子或引用提出索賠。我不知道boost是否能夠完成我需要的預處理功能,但是它是一個非常大的代碼,無需任何特定的指針即可查看。如果你能展示一個可以解決這個問題的例子,那麼這將是有用的 - 否則就像說「是的,這是可能的,但是你必須在那裏自己找到那一大堆神祕的圖書館代碼」 - 不是很很有幫助。 – viraptor 2010-07-17 20:43:30

+2

@viraptor:我沒有舉例,因爲它真的很複雜(正如我所說的),並且不適合這裏的適當答案。 (好吧,我沒有給出提升的參考,但我想你可以找到它。)其次,boost的預處理器部分並不是那麼神祕,我發現。它完全符合你在接受答案時所要求的條件。然後在沒有給出理由或要求更多信息的情況下下調投票也沒有多大幫助。僅僅是粗魯的,我會通過尋求幫助的人說。 – 2010-07-17 21:03:00