什么是__stdcall?
我正在学习Win32编程, WinMain
原型如下所示:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
我很困惑这个WINAPI
标识符是什么,并发现:
#define WINAPI __stdcall
这是做什么的? 我很困惑,因为在返回types之后有什么东西。 什么是__stdcall
? 返回types和函数名称之间有什么意义时,这意味着什么?
__stdcall
是用于该函数的调用约定。 这告诉编译器适用于设置堆栈,推入参数和获取返回值的规则。
还有一些其他的调用约定, __thiscall
, __thiscall
, __thiscall
和奇妙的__naked
。 __stdcall
是Win32系统调用的标准调用约定。
维基百科涵盖了细节 。
当你在你的代码之外调用一个函数(例如一个OS API)或者操作系统正在调用你时(这和WinMain的情况一样),这主要是重要的。 如果编译器不知道正确的调用约定,那么你可能会得到非常奇怪的崩溃,因为堆栈将无法正确pipe理。
C或C ++本身不定义这些标识符。 它们是编译器扩展,代表某些调用约定。 这决定了将参数放在哪里,以何种顺序,被调用的函数将find返回地址,依此类推。 例如,__fastcall表示函数的参数通过寄存器传递。
维基百科文章提供了在那里find的不同调用约定的概述。
到目前为止的答案已经涵盖了细节,但如果你不打算下拉到assembly,那么你所要知道的是,调用者和被调用者必须使用相同的调用约定,否则你会得到一些错误很难find。
我同意迄今为止所有答案都是正确的,但这是原因。 微软的C和C ++编译器为应用程序的C和C ++函数中(函数调用)的速度提供了各种调用约定。 在每种情况下,主叫方和被叫方必须就使用哪种调用约定达成一致。 现在,Windows本身提供了函数(API),而且这些函数已经被编译,所以当你调用它们时,你必须遵守它们。 任何对Windows API的调用以及Windows API的callback都必须使用__stdcall约定。
它与函数的调用方式有关,基本上就是把事物放在堆栈上的顺序以及谁负责清理。
这里是文档,但是除非你理解第一部分,否则它并不意味着太多。
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
__stdcall用于将函数参数放入堆栈。 该function完成后,它会自动解除分配内存。 这用于固定参数。
void __stdcall fnname ( int, int* ) { ... } int main() { CreateThread ( NULL, 0, fnname, int, int*...... ) }
这里fnname有args它直接推入堆栈。
直到今天,我从来没有使用过。 因为在我的代码中,我正在使用multithreading,而我正在使用的multithreadingAPI是windows(_beginthreadex)。
开始线程:
_beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0);
ExecuteCommand函数必须在方法签名中使用__stdcall关键字,以便beginthreadex调用它:
unsigned int __stdcall Scene::ExecuteCommand(void* command) { return system(static_cast<char*>(command)); }