c++++ 中的函数调用约定定义了调用函数时参数和返回值的传递方式,影响函数调用栈和函数指针的行为。不同的函数调用约定:cdecl:参数从右到左压入栈,返回值在 eax/rax 寄存器中返回。stdcall:参数压栈,返回值在 eax/rax 中返回,调用方清理栈。fastcall:前两个参数通过寄存器传递,其余压栈,返回值在 eax/rax 中返回。thiscall:前一个参数(this 指针)通过寄存器传递,其余压栈,返回值在 eax/rax 中返回。选择合适的调用约定基于性能
C++ 中的函数调用约定
在 C++ 中,函数调用约定定义了在调用函数时如何传递参数和返回值。它影响着函数调用栈和函数指针的行为。
不同的函数调用约定
立即学习“C++免费学习笔记(深入)”;
C++ 中有几种不同的函数调用约定:
- cdecl:参数从右到左压入栈中,返回值在 EAX/RAX 寄存器中返回。
- stdcall:参数从右到左压入栈中,返回值在 EAX/RAX 寄存器中返回,但调用方负责清理栈。
- fastcall:前两个参数通过 ECX/RCX 和 EDX/RDX 寄存器传递,其余参数压入栈中。返回值在 EAX/RAX 寄存器中返回。
- thiscall:前一个参数(this 指针)通过 ECX/RCX 寄存器传递,其余参数压入栈中。返回值在 EAX/RAX 寄存器中返回。
实战案例
以下是如何在 C++ 中使用不同函数调用约定的示例:
// cdecl 调用约定
int cdecl_func(int a, int b) {
return a + b;
}
// stdcall 调用约定
int stdcall_func(int a, int b) {
return a * b;
}
// fastcall 调用约定
int fastcall_func(int a, int b, int c) {
return a + b + c;
}
// thiscall 调用约定
class MyClass {
public:
int thiscall_func(int a, int b) {
return a - b;
}
};
int main() {
int result = cdecl_func(1, 2);
result = stdcall_func(3, 4);
result = fastcall_func(5, 6, 7);
MyClass my_class;
result = my_class.thiscall_func(8, 9);
return 0;
}
选择正确的调用约定
选择正确的函数调用约定取决于以下因素:
- 性能要求
- 平台和编译器
- 参数和返回值的数量和大小
- 是否需要回调
通常,cdecl 适用于大多数情况,而其他调用约定在特定场景中可能更有效。