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.

解决方案 »

  1.   

    被调用方清除堆栈,因而编译器会把可变参数的函数按_cdecl调用。使用这种调用约定的函数需要声明一个函数原型。
      

  2.   

    1。
    补充完整后觉得不通顺:_stdcall调用约定,被用来调用 Win32 API  函数,被调用方清除堆栈,因而编译器会把可变参数的函数按_cdecl调用。使用这种调用约定的函数需要声明一个函数原型。----------------------------------------------------
    2。
    callee -- 被调用方
    vararg -- 可变参数上面的单词是这意思吗?
      

  3.   

    调用约定规定了由谁来恢复堆栈,仅从C代码上看不出区别,从汇编或编译的角度比较容易理解.
    以下面的代码为例, 在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. 
    这里有一个思维跳跃,假设你对调用约定的机制已了解,由前面的半句话自然而然可以得出后面的结论。