2012-10-20 63 views
0

當閱讀Enlightenment's代碼時,我發現一些關於C的東西我不明白。我會貼上線條並解釋爲什麼它不清楚。我不明白的C代碼

Eina_Bool (*hide)(void *data, Evas_Object *o); 
void (*del)(void *data, Evas_Object *o); 

在這個問題上,括號之間的那個指針值是什麼意思就是返回值之後? 另請注意,這兩個函數的第一個參數是void *data。這是否意味着您可以將指針傳遞給函數的任何類型的數據?

EAPI Ecore_X_Window elm_win_xwindow_get(const Evas_Object *obj); 

幾乎API上的所有功能都以EAPI開頭。那是什麼意思?它是一種名稱空間嗎?我在哪裏可以找到關於這方面的信息?

另請注意他們如何使用其中的一個庫:Elementary

EAPI_MAIN int elm_main(int argc, char **argv) { 
    // CODE 
} 
ELM_MAIN() 

而不是使用一個主要功能,您使用elm_main再次與那些大寫標誌:EAPI_MAIN。 而剛纔的功能有奇怪的ELM_MAIN()沒有分號。

如果你們在我第一次看到他們的時候向我解釋一些看起來很奇怪的東西,我會很感激。

注意:我粘貼的所有示例都來自elm_win.h小標題。

+0

對於第一個問題,它們是函數指針。 EAPI是一個空的定義,可能僅用於註釋代碼。 ELM_MAIN()是定義要調用elm_init的main()函數,並調用elm_main – nhahtdh

回答

2

,你在這裏展示的線是函數指針變量的聲明。

形式的A線:

int (*foo)(int x) 

例如聲明變量名爲foo,可容納(的地址),它有一個整數參數(x)並返回一個整數的函數。如果你聲明瞭這樣一個函數:

int twice(int x) 
{ 
    return x*2; 
} 

你可以將該函數賦給變量foo(的地址)。

foo = twice; 

,然後你可以通過指針調用函數twice

int result = foo(3); 

result現在將包含6)

通常的原因,以使這樣的事情是,你知道你想要在代碼中的某個點調用某個函數,但究竟是哪個函數依賴於其他代碼。如果你在函數調用process_Aprocess_B您就可以將其中的一個函數變量:

int (*process)(int x); 
process = using_b ? process_B : process_A; 
... more code ... 
result = process(some_value); 

這裏的結果設置爲具體取決於被分配到process無論是process_Aprocess_B計算的值,

您可以使用條件在調用點,當然,但選擇的功能,並在一個變量它(或者更確切地說,它的地址)存儲導致更有效和(更重要的)更清晰的代碼。

至於EAPI符號......我不知道啓蒙運動,但我希望是,這只是在頭#define的宏。它可能會根據構建選項更改調用約定或導出符號。

+0

非常感謝,驚人的,clearn解釋:) – jviotti

0

那些前兩個語句是函數指針定義。即指向一個函數地址的指針變量。

void *類型可以接受任何有效的指針值或空指針。必須以某種方式記錄指針指向的實際類型,以便正確地將void *轉換爲實際的類型bahind。這是常用的方法,可以將任意用戶類型的數據傳遞給回調函數。這就是兩個函數指針的用途。

此語句

Eina_Bool (*hide)(void *data, Evas_Object *o); 

指:隱藏是一個指針,指向作爲參數接受一個void *,一個Evas_Object *並返回一個​​的功能。

注意,這給subtely不同的語句

Eina_Bool* reveal(void *data, Evas_Object *o); 

這將是一個功能叫reveal返回Eina_Bool*顯着不同。

0

我發現this source定義EAPI

#ifdef _WIN32 
# ifdef EFL_EFX_BUILD 
# ifdef DLL_EXPORT 
# define EAPI __declspec(dllexport) 
# else /* ifdef DLL_EXPORT */ 
# define EAPI 
# endif /* ! DLL_EXPORT */ 
# else /* ifdef EFL_BUILD */ 
# define EAPI __declspec(dllimport) 
# endif /* ! EFL_BUILD */ 
#else /* ifdef _WIN32 */ 
# ifdef __GNUC__ 
# if __GNUC__ >= 4 
# define EAPI __attribute__ ((visibility("default"))) 
# else /* if __GNUC__ >= 4 */ 
# define EAPI 
# endif /* if __GNUC__ >= 4 */ 
# else /* ifdef __GNUC__ */ 
# define EAPI 
# endif /* ifdef __GNUC__ */ 
#endif /* ! _WIN32 */ 

這些都是編譯器標誌。

現在,關於你的hidedel的問題;這些不是功能,但功能指針。也就是說,如果你解引用del,你會得到這種類型的函數:

void del_impl(void *data, Evas_Object *o); 

這允許運行時選擇哪個函數基於在線數據調用。