2013-04-18 27 views
2

#定義我有這樣的代碼:如何在宏(或替代)

#ifdef something32       <----- might not be defined 
    the_real_value = thing[something32]; 
    thing[something32] = my_value; 
#else 
    the_real_value = thing[something]; <------- guarantied to be defined (something) 
    thing[something] = my_value; 
#endif 

#ifdef THE_OTHER_THING      <--------- might not be defined 
#ifdef something32 
    thing32[something32] = my_value; 
#else 
    thing32[something] = my_value; 
#endif 
#endif 

,我會使用很多次,所以我想用宏來替換它。我知道#ifdef無法生存宏,所以我想知道如何替換所有代碼。有任何想法嗎?

編輯:

對不起,我忘了提,something32僅僅是一個相當長的變量列表中的一個。

的想法是有一些像

SHORTEN_MY_CODE(something, something32); 
SHORTEN_MY_CODE(another_something, another_something32); 
etc... 
+0

'#ifdefs'不能在宏中,但宏可以在#ifdef中。 –

+0

@CarlNorum對不起,我會編輯我的問題,你會明白我爲什麼不能使用它。 – alexandernst

+0

我認爲有一個正確的方式來做你想做的事情,但我需要看到你的代碼的其餘部分來幫助。 –

回答

2

把你的邏輯周圍,將宏定義什麼爲依據的條件 - 而不是定義包含條件的宏:

// define 

#ifdef something32 
    #define SOMETHING_VAR something32 
#else 
    #define SOMETHING_VAR something 

#define SHORTEN_MY_CODE the_real_value = thing[SOMETHING_VAR]; \ 
    thing[SOMETHING_VAR] = my_value; 

#ifdef THE_OTHER_THING 
    #define SHORT_OTHER() thing32[SOMETHING_VAR] = my_value 
#else 
    #define SHORT_OTHER() 
#endif 

// usage 
SHORTEN_MY_CODE() 
SHORT_OTHER() 

原來的答案

#ifdef something32 
    #define MY_MACRO the_real_value = thing[something32]; \ 
    thing[something32] = my_value; 
#else 
    #define MY_MACRO the_real_value = thing[something]; \ 
    thing[something] = my_value; 
#endif 
+0

對不起,我的編輯 – alexandernst

+0

@alexandernst是否必須使用#ifdef或可以使用三進制。編譯器會優化在這種情況下永遠不會發生的分支 –

+0

不,我不能定義'''something32'''。無論如何,''''''''是擔保被定義的。 – alexandernst

0

如果你正在做C++,我會考慮寫一個函數並聲明它內聯。如果你有一個完整的功能,那麼你可以在函數中加入#ifdef。

如果您發佈了更多代碼,我認爲我們可以提供更多幫助。濫用c預處理器非常猖獗。你可能不想按照你的建議來使用它。

我不明白somethingsomething32OTHER_THING如何定義。它們是在項目級別還是在某個頭文件中定義的?


更新:建議。但是,您可能想先閱讀:access to the sys_call_table in kernel 2.6+

void* Hook(int f, void* hooked) { 
#ifdef CONFIG_IA32_EMULATION 
    void *old = ia32_sys_call_table[f]; 
    ia32_sys_call_table[f] = hooked; 
#else 
    void *old = sys_call_table[f]; 
    sys_call_table[f] = hooked; 
#endif 
    return old; 
} 


... 

Hook(__NR_read, hooked_sys_read); 
Hook(__NR_write, hooked_sys_write); 
+0

我使用的是C/C++,所以這是一個選項。 OTHER_THING是CONFIG_IA32_EMULATION(Linux Kernel),而something和something32是' ''(sys_calls)。 '''__NR_read'''將永遠存在,不管架構如何,只有''__NR_read32'''只會在x64和IA32仿真激活時才存在。另外,請記住,這不是唯一的sys_call(還有更多)。 – alexandernst

+0

仍然需要更多示例代碼......如果您正在使用庫符號(如'__NR_read')作爲某些數組的偏移量,那麼顯然您會玩火。如果你用C編寫彙編代碼,你使用的是錯誤的工具.... –

+0

好的,這裏是實際的代碼:https://github.com/alexandernst/procmon/blob/master/syshijack.h和https:/ /github.com/alexandernst/procmon/blob/master/hookfns.c – alexandernst