__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的线程函数地址