2012-03-01 46 views
1

例如:定義調用約定有什麼意義?

int WINAPI WinMain (HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show) 

WINAPI是AA定義是這樣的:

#define WINAPI  __stdcall 

爲什麼你就不能這樣做:

int __stdcall WinMain (HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show) 

其實我覺得我的問題是,我有點令人困惑的定義與typedef的。誰可以給我解釋一下這個?定義是做什麼的,爲什麼不能在它的地方寫入__stdcall?

回答

3

因爲WINAPI調用約定不是保證__stdcall。即使不是,代碼使用WINAPI仍然是正確的。

可以寫你的後一個例子中的函數,它會工作正常 - 這不是好的做法,並且不能移植到調用約定是別的平臺。

+0

呃,其實你錯了。因爲現在不可能改變這個習俗。試想一下,如果microsoft突然將WINAPI更改爲__cdecl,那麼每個使用Win Api頭版的先前版本編譯的程序都將無法正常工作 – 2012-03-01 17:00:11

+0

不過,對於不同的平臺來說,這是有意義的。只有x86具有'__stdcall',所以期望WINAPI在ARM上成爲一個空宏。 – 2012-03-01 17:00:55

+0

@kids_fox顯然,二進制文件不會有效,但代碼會。 – 2012-03-01 17:02:14

3

可以只需在它的位置寫__stdcall,但不要。他們已經認爲適合#定義WINAPI爲__stdcall來使這個不透明,這只是一個很好的編程習慣。

4

這最初是在從16位代碼切換到32位代碼期間完成的。在<windows.h>的16位版本是:

#define WINAPI __pascal 

WINAPI讓你編譯或者沒有修改源代碼。當然,16位Windows不再是一個因素(至少對於大多數人來說),但是直接使用__stdcall直接使用並不值得修改所有源代碼(尤其是因爲它可能會在某一天再次更改)。

2

此外,當天,一些Windows庫使用Pascal調用約定和其他庫使用C約定。預處理器定義有助於理解這一點。

1

因爲WINAPI是一個宏(無論如何都是#define),它可以被「預處理」爲意味着別的東西甚至什麼也不是。

這意味着您可以編寫更多可移植的代碼,因爲您可以在WIN32需要時指定__stdcall而將其放在WINAPI中,或者如果在另一個環境中需要它來表示其他內容或不需要時,您可以編寫更多可移植代碼。