__cdecl 是微软编译器支持的C language extension。它明确指定应使用“cdecl”调用约定调用函数,这与在调用函数之前和之后应如何设置寄存器状态和堆栈的内部结构有关,以便传递参数和返回值.
在您的代码 sn-p 中,PullDown 被定义为具有三个参数的函数,其中前两个是 char ** 和 int。
函数的最后一个参数void (__cdecl **)(void) 是一个指针,该指针指向一个具有 cdecl 调用约定的函数的指针,该函数没有返回值,也没有参数。
为了分解这个声明,我们现在可以完全删除__cdecl,并为这个参数添加一个变量名:
void (**param)(void)
声明中的* 运算符指定它右边的表达式是一个指针,所以这意味着param 是一个指针,而*param 也是一个指针(因此param 是一个指向一个指针)。为了理解这个指针所指向的内容,**param 现在可以用占位符 foobar 代替,得到以下内容:
void (foobar)(void)
这现在有一对多余的括号,等效于以下内容:
void foobar(void)
这现在看起来像一个常规函数声明,返回 void 和 void 参数(没有参数也没有返回值)。因此param 是一个指向具有此签名的函数的指针。
最后,__cdecl适用于它右边的表达式,由于**param代表函数,__cdecl可以加到**param的左边,表示这个函数有cdecl调用约定:
void (__cdecl **param)(void)
您的代码 sn-p 中的参数只是删除了参数名称 param,与从 char **param 和 int param 中删除的方式相同。
一般来说,cdecl 调用约定应该是使用 Visual Studio 编译 C 和 C++ 代码时的默认值,因此显式指定 __cdecl 应该是多余的。但是,有时需要指定一个函数具有 __stdcall 调用约定,例如,在处理函数指针时确保 stdcall 函数仅通过 __stdcall 函数指针和 cdecl 函数调用是很重要的通过__cdecl 函数指针调用(这应该是默认值)。尝试使用错误的调用约定调用函数很可能会使您的程序崩溃或使其处于不确定状态。