Microsoft SpecificThe __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype.就译下面的就可以了:
The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype.
The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype.
补充完整后觉得不通顺:_stdcall调用约定,被用来调用 Win32 API 函数,被调用方清除堆栈,因而编译器会把可变参数的函数按_cdecl调用。使用这种调用约定的函数需要声明一个函数原型。----------------------------------------------------
2。
callee -- 被调用方
vararg -- 可变参数上面的单词是这意思吗?
以下面的代码为例, 在main函数中调用了foo和fooV
void WINAPI foo(void *pv);
void fooV(LPCTSTR *lpszFmt, ...); //...表示vararg, 表示后面的参数个数不固定.int main()
{
...
foo(pv);
fooV("%s\r\n", sz);
...
}
在main中分别调用了foo和fooV, 对于main函数而言,main称为caller, foo和fooV称为callee
调用函数时会先将参数压入堆栈,如foo等价于
push pv
call foofooV等价于
push ...
push ...
push lpszFmt
call fooV由于foo知道确切的参数个数, 因而当foo函数返回时(ret), 按照调用规则,将由它通过pop来恢复堆栈.
对于含有可变参数的函数,如fooV,由于不知道参数的具体个数, 不可能由fooV来清除堆栈,只能交由调用者(main)来做(编译器会将它视为__cdecl约定)。The callee cleans the stack, so the compiler makes vararg functions __cdecl.
这里有一个思维跳跃,假设你对调用约定的机制已了解,由前面的半句话自然而然可以得出后面的结论。