2010-06-19 91 views
3

我來到翻過一個代碼段,用於檢測應用是否在X32仿真環境中運行的x64 PC上 here指向函數的指針和指向WINAPI函數的指針有什麼區別?

一般來說,我明白的代碼,但有一件事我不明白:

1)的typedef BOOL (WINAPI * LPFN_ISWOW64PROCESS)(HANDLE,PBOOL);

爲什麼WINAPI必須在那裏?爲什麼知道指針不指向我定義的函數而是指向WINAPI函數非常重要?這兩個指針會不一樣? (大小的方式,將他們創建等)

感謝,

克拉

回答

4

WINAPI擴展爲__stdcall(在大多數情況下 - 您不應該特別依賴該調用約定),這是與默認__cdecl不同的調用約定。不同的是,在__stdcall中,調用的函數清除堆棧,而在__cdecl中,調用者清除堆棧。 __stdcall不支持像__cdecl那樣的可變參數長度函數,但__stdcall在某些情況下可以更快並且減少代碼大小。

+0

因此,簡而言之,WINAPI說編譯器在函數完成後不生成代碼來清理棧上的亂碼? – Kra 2010-06-19 07:01:39

+0

@Kra:大部分,是的。我不知道如何轉換成x86_64,但x86的情況絕對如此。 – 2010-06-19 07:20:48

+0

很酷,它是有道理的,當WINAPI被刪除時,編譯器不會呻吟,並且該應用程序崩潰與信息,ESP值沒有正確保存在函數調用。感謝您分享您的知識:) – Kra 2010-06-19 07:31:45

1

WINAPI宏觀通常包含與WinAPI的功能實現特定的聲明細節。就像一個調用約定。上述指針可以指向任何函數,只要它遵循與WinAPI函數相同的調用約定。

這個宏拼寫爲WINAPI的事實沒有任何意義。它可能拼寫爲AHELLO_WORLD或其他。這個宏的全部和唯一一點是提供一個地方,其中描述了所有這些WinAPI特定的約定,以便萬一發生了某些變化,您只需要在一個地方修改它。

它可能很容易成爲一個無法解決的宏。

0

同意以前的帖子。 順便說一句我真的不明白爲什麼__cdecl仍然被認爲是C/C++的「默認」調用約定。

很顯然,使用__cdecl的結果是比__stdcall略大一點的代碼,因爲該函數只寫了一次,通常從幾個代碼段中調用。是的,__cdecl更靈活,因爲它允許可變參數長度。但是,只有用於標記爲...的適當功能,才能使用此手機。

例如對於成員函數調用(又名thiscall)Msvc完全是這樣的:使用__stdcall -like調用約定,除非該函數接受可變參數。 (另外this通過ECX寄存器傳遞)。

+0

@valdo:您必須將其與編譯器供應商合作。 C++不會說關於調用約定的問題,除了'extern「C」'被允許改變調用約定。 – 2010-06-19 08:03:46