微软特别声明:
调用约定__stdcall被用来调用Win32 API(32位Windows应用平台接口)函数。由于该调用会清理栈,所以编译器使用vararg函数__cdecl。函数在使用这个调用约定需要指定一个函数原型。
return-type __stdcall function-name[(argument-list)]
返回值类型 __stdcall 函数名[(参数表)]
备注:
下面的表格中显示了调用约定的执行状况
项目 | 执行状况 |
参数传递方向 | 从右向左 |
常规参数传递 | 通过值传递,除非小数点或者引用类型已经通过 |
栈的相关操作 | 被调用函数将其参数从栈中做出栈处理 |
函数名修饰法 | 一个下划线(_)作为函数名的前缀。这个名字后跟着一个at符(@)与参数表的字节数(使用小数表示)。因此,这个被描述为int func(int a, double b)的函数将被修饰为_func@12 |
案例翻译法 | 没有 |
/Gz编译选项为所有没有明确描述不同调用方式的函数指定__stdcall修饰符
使用__stdcall修饰符描述的函数的返回值方式与使用__cdecl修饰符描述的函数一样
在安腾处理器(IPF)以及64位处理器中,__stdcall可以被接受并被编译器忽略;在安腾处理器中,通过约定,参数被传递至寄存器中。
对于非静态类函数,如果这个函数被定义为(out-of-line 乱线?),这个调用约定修饰符不必指定(out-of-line 乱线?)的定义。也就是说,对于非静态成员模式,这个调用约定被指定在假设定义的这一点上。
获取这个类的定义,
struct CMyClass {
void __stdcall mymethod();
}
void __stdcall mymethod();
}
这个
void CMyClass::mymethod() { return;}
等价于
void __stdcall CMyClass::mymethod() { return;}
例子:
在下面的例子中,使用__stdcall的结果是所有的WINAPI函数类型被处理为标准调用
// __stdcall关键字的例子
#define WINAPI __stdcall
// 使用__stdcall关键字的指针函数的例子
typedef BOOL (__stdcall *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);
#define WINAPI __stdcall
// 使用__stdcall关键字的指针函数的例子
typedef BOOL (__stdcall *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);
转载于:https://blog.51cto.com/starry/146427