__cdecl
is a C语言扩展 https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx微软编译器支持。它明确指定应使用“cdecl”调用约定来调用函数,这涉及在调用函数之前和之后应如何设置寄存器和堆栈状态的内部原理,以便传递参数和返回值。
在您的代码片段中,PullDown
被定义为具有三个参数的函数,其中前两个是char **
and an int
.
函数的最后一个参数,void (__cdecl **)(void)
,是一个指向具有 cdecl 调用约定的函数的指针,该函数没有返回值且不带任何参数。
为了打破这个声明,我们可以删除__cdecl
现在完全完成并为此参数添加一个变量名称:
void (**param)(void)
The *
声明中的运算符指定其右侧的表达式是指针,因此这意味着param
是一个指针,并且也是*param
是一个指针(因此param
是一个指向指针的指针)。要理解这个指针指向什么,**param
可以用占位符替换foobar
现在给出以下内容:
void (foobar)(void)
现在有一对多余的括号,相当于以下内容:
void foobar(void)
现在看起来像一个常规函数声明返回void
with a void
参数(无参数且无返回值)。所以param
是一个指向具有此签名的函数的指针。
Lastly, __cdecl
适用于它右边的表达式,并且因为**param
代表函数,__cdecl
可以添加到左侧**param
表明该函数具有 cdecl 调用约定:
void (__cdecl **param)(void)
代码片段中的参数只有参数名称param
删除,以同样的方式删除char **param
and int param
.
一般来说,使用 Visual Studio 编译 C 和 C++ 代码时,cdecl 调用约定应该是默认的,因此指定__cdecl
明确应该是多余的。然而,有时需要指定一个函数具有__stdcall
例如,调用约定,在处理函数指针时确保 stdcall 函数仅通过调用非常重要__stdcall
函数指针和 cdecl 函数只能通过以下方式调用__cdecl
函数指针(这应该是默认值)。尝试使用错误的调用约定调用函数很可能会使您的程序崩溃或使其处于不确定状态。