函数的调用约定包括了函数的参数如何被压入栈中、函数调用后由谁来恢复堆栈等问题1

常见的调用约定2

调用约定名称 常见场景 参数入栈方式 栈内数据清除方式 备注
__stdcall Windows API 默认的函数调用协议 函数参数由右向左入栈 函数调用结束后由被调用函数清除栈内数据 -
__cdecl C/C++ 默认的函数调用协议 函数参数由右向左入栈 函数调用结束后由函数调用者清除栈内数据 -
__fastcall 适用于对性能要求较高的场合 从左开始不大于 4 字节的参数放入 CPU 的 ECX 和 EDX 寄存器,其余参数从右向左入栈 函数调用结束后由被调用函数清除栈内数据 -
__thiscall C++ 类成员函数缺省的调用约定 函数参数由右向左入栈 见下文 这个不是编译器关键字,在 C++ 编译中不能被程序员指定
naked call 很少见,一般用于实模式驱动程序设计3 - - -
__pascal4 Pascal 的函数调用方式,也可以在 C/C++ 中使用 函数参数由左向右入栈 函数调用结束后由被调用函数清除栈内数据 -

__thiscall

看了不少博客,但还是看巨硬的文档比较详细: https://learn.microsoft.com/zh-cn/cpp/cpp/thiscall?view=msvc-170

mangle

不同的规范有不同的 mangle 规定,这也是 C 和 C++ 函数之间不能直接调用的原因

所以一般会有下面这种语法:

extern "C" {
    // ...
}

这样里面的函数声明才能被 C 所使用,或使用 C 定义的函数