函数指针 设置调用约定
时间: 2023-11-22 13:44:20 浏览: 52
函数指针可以设置调用约定,以指定函数调用时参数的传递方式、寄存器的使用方式等。常见的调用约定有 cdecl、stdcall、fastcall 等。
其中 cdecl 是默认的调用约定,参数从右往左依次入栈,由调用者负责清理栈空间;stdcall 则是参数从右往左依次入栈,由被调用函数负责清理栈空间;fastcall 则是将前两个参数放在寄存器中传递,可以提高函数调用的效率。
相关问题
C++ 函数调用约定
C++函数调用约定是指在编译器编译函数时,函数的参数如何被压入堆栈,返回值如何从堆栈中弹出等规则。常见的C++函数调用约定有三种:stdcall、cdecl和thiscall。
stdcall是一种被广泛使用的函数调用约定,它要求被调用的函数自己清理堆栈。stdcall约定的函数参数是从右往左依次压入堆栈中的,返回值通常存放在EAX寄存器中。
cdecl是C/C++默认的函数调用约定,它要求调用者清理堆栈。cdecl约定的函数参数也是从右往左依次压入堆栈中的,返回值通常存放在EAX寄存器中。
thiscall是一种微软的函数调用约定,它用于成员函数的调用。thiscall约定的函数参数是从右往左依次压入堆栈中的,返回值通常存放在EAX寄存器中,同时this指针会被压入ECX寄存器中。
下面是一个使用stdcall约定的C++函数的例子:
```cpp
#include <iostream>
using namespace std;
// 声明使用stdcall约定
int __stdcall add(int a, int b);
int main() {
int a = 1, b = 2;
int sum = add(a, b);
cout << "sum = " << sum << endl;
return 0;
}
// 定义使用stdcall约定
int __stdcall add(int a, int b) {
return a + b;
}
```
有函数地址如何调用函数
要调用kernel32中的函数,需要先获取函数的地址。可以使用GetModuleHandle函数获取kernel32.dll的基地址,然后使用GetProcAddress函数获取函数的地址。例如,要调用MessageBox函数:
1. 获取kernel32.dll的基地址:
HMODULE hModule = GetModuleHandle(L"kernel32.dll");
2. 获取MessageBox函数的地址:
FARPROC pFunc = GetProcAddress(hModule, "MessageBoxW");
3. 调用MessageBox函数:
int nRet = ((int(WINAPI*)(HWND, LPCWSTR, LPCWSTR, UINT))pFunc)(NULL, L"Hello World", L"Message", MB_OK);
其中,WINAPI是函数的调用约定,HWND、LPCWSTR、LPCWSTR和UINT是MessageBox函数的参数类型,pFunc是MessageBox函数的地址,((int(WINAPI*)(HWND, LPCWSTR, LPCWSTR, UINT))pFunc)是将pFunc转换为函数指针类型,然后再调用函数。