__declspec一般是ms對標準c++語言的擴充指令.經典的象dllexport,property(get=...)等等.不想跨平臺用用不錯.

__cdecl,__stdcall是聲明的函數調用協議.主要是傳參和彈棧方面的不同.一般c++用的是__cdecl,windows里大都用的是__stdcall(API)


函數調用規范__cdecl和__stdcall的區別一目了然(表格形式) 轉載- -

Tag__cdecl ?? __stdcall ?? 區別 ?? ??????????????????????????????????????

?

__cdecl

?

?

__stdcall

?

CC++程序的缺省調用規范

?

為了使用這種調用規范,需要你明確的加上__stdcall(或WINAPI)文字。即return-type__stdcallfunction-name[(argument-list)]

?

?

調用函數(Callee)返回,由調用者(Caller)調整堆棧。

?

調用者

??? // call function
??? // adjust stack

?

被調用函數
??? // do work
??? // return

?

調用函數(Callee)返回,由調用函數(Callee)調整堆棧。圖示:

?

調用者

??? // call function

?

被調用函數
??? // do work
??? // adjust stack
??? // return

?

因為每個調用的地方都需要生成一段調整堆棧的代碼,所以最后生成的文件較大。

?

?

因為調整堆棧的代碼只存在在一個地方(被調用函數的代碼內),所以最后生成的文件較小。

?

函數的參數個數可變(就像printf函數一樣),因為只有調用者才知道它傳給被調用函數幾個參數,才能在調用結束時適當地調整堆棧。

?

?

函數的參數個數不能是可變的。

?

對于定義在C程序文件中的輸出函數,函數名會保持原樣,不會被修飾。

對于定義在C++程序文件中的輸出函數,函數名會被修飾, MSDNUnderscore character (_) is prefixed to names. 我實際測試(VC4VC6)下來發現好像不是那么簡單。

可通過在前面加上extern “C”以去除函數名修飾。也可通過.def文件去除函數名修飾。

?

不論是C程序文件中的輸出函數還是C++程序文件中的輸出函數,函數名都會被修飾。

對于定義在C程序文件中的輸出函數,An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list.

對于定義在C++程序文件中的輸出函數,好像更復雜,和__cdecl的情況類似。

好像只能通過.def文件去除函數名修飾。

?

?

_beginthread需要__cdecl的線程函數地址

?

?

_beginthreadexCreateThread需要__stdcall的線程函數地址