函数声明中的 WINAPI 标识符 DLL 入口函数中的 C++
WINAPI identifiers in function declaration C++ in DLL entrypoint function
我正在学习如何使用 C++ 创建 dll。
出现这个:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
而且我不明白 DllMain()
中的 "WINAPI"
是什么?
我知道一个函数是:
typeReturn functionName (params) { function body }
typeReturn
: 是函数 returns,
的值
functionName
: 是函数名,
params
: 是函数的参数,
{function body} : 是函数里面的代码。
...
那么按照解释,WINAPI
在C++中是什么意思,或者__stdcall
?
我不是在问 WINAPI
本身是什么意思。
************ 更新 ***************
C++ 有(调用约定)用于将以特殊方式给出的每个参数放入内存。
请正确阅读问题并避免将其标记为重复,因为学习 c/c++ 的人需要学习而不陷入混乱
Dynamic-Link库,在Windows操作系统中使用,所以DLL函数的入口点如果是运行在Windows.
WINAPI
定义为 __stdcall
.
其实__stdcall
是一个调用约定而且不同的调用约定推送参数的方式不同,下面是一些c/c++
调用约定:
在 x86 中:
C
调用约定 (__cdecl
)。 __cdecl
调用约定的主要特点是:
- 参数从右向左传递,并入栈。
- 堆栈清理由调用者执行。
- 函数名称通过在其前面加上下划线字符 '_' 进行修饰。
标准调用约定 (__stdcall
)。 __stdcall
调用约定的主要特点是:
- 参数从右向左传递,并入栈。
- 堆栈清理由调用的函数执行。
- 函数名通过在前面加上一个下划线字符并附加一个'@'字符和所需的堆栈字节数space来修饰。
快速调用约定 (__fastcall
)。 __fastcall
调用约定的主要特征是:
- 前两个需要 32 位或更少位的函数参数被放入寄存器 ECX 和 EDX。其余的从右到左压入堆栈。
- 被调用函数从堆栈中弹出参数。
- 函数名是通过在
'@'
字符前加一个'@'
和参数所需的space字节数(十进制)来修饰的。
在 x64 中:
在 x64
中,只有 __fastcall
存在。忽略所有其他属性。
x64
应用程序二进制接口 (ABI) 默认使用四寄存器 fast-call 调用约定。
注意事项:
当你调用一个函数时,在汇编级别发生的事情是所有传入的参数被压入堆栈或放入寄存器或放入静态存储,然后程序跳转到不同的代码区域。新的代码区域查看堆栈并期望将参数放在那里。
不同的调用约定以不同的方式推送参数。有些人可能会先推送第一个参数,有些人可能会最后推送第一个参数。或者有些人可能将参数保存在寄存器中,根本不推送它。
通过指定调用约定,您告诉编译器如何推送参数。
我正在学习如何使用 C++ 创建 dll。
出现这个:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
而且我不明白 DllMain()
中的 "WINAPI"
是什么?
我知道一个函数是:
typeReturn functionName (params) { function body }
typeReturn
: 是函数 returns,
的值
functionName
: 是函数名,
params
: 是函数的参数,
{function body} : 是函数里面的代码。
...
那么按照解释,WINAPI
在C++中是什么意思,或者__stdcall
?
我不是在问 WINAPI
本身是什么意思。
************ 更新 ***************
C++ 有(调用约定)用于将以特殊方式给出的每个参数放入内存。 请正确阅读问题并避免将其标记为重复,因为学习 c/c++ 的人需要学习而不陷入混乱
Dynamic-Link库,在Windows操作系统中使用,所以DLL函数的入口点如果是运行在Windows.
WINAPI
定义为 __stdcall
.
其实__stdcall
是一个调用约定而且不同的调用约定推送参数的方式不同,下面是一些c/c++
调用约定:
在 x86 中:
C
调用约定 (__cdecl
)。__cdecl
调用约定的主要特点是:- 参数从右向左传递,并入栈。
- 堆栈清理由调用者执行。
- 函数名称通过在其前面加上下划线字符 '_' 进行修饰。
标准调用约定 (
__stdcall
)。__stdcall
调用约定的主要特点是:- 参数从右向左传递,并入栈。
- 堆栈清理由调用的函数执行。
- 函数名通过在前面加上一个下划线字符并附加一个'@'字符和所需的堆栈字节数space来修饰。
快速调用约定 (
__fastcall
)。__fastcall
调用约定的主要特征是:- 前两个需要 32 位或更少位的函数参数被放入寄存器 ECX 和 EDX。其余的从右到左压入堆栈。
- 被调用函数从堆栈中弹出参数。
- 函数名是通过在
'@'
字符前加一个'@'
和参数所需的space字节数(十进制)来修饰的。
在 x64 中:
在 x64
中,只有 __fastcall
存在。忽略所有其他属性。
x64
应用程序二进制接口 (ABI) 默认使用四寄存器 fast-call 调用约定。
注意事项: 当你调用一个函数时,在汇编级别发生的事情是所有传入的参数被压入堆栈或放入寄存器或放入静态存储,然后程序跳转到不同的代码区域。新的代码区域查看堆栈并期望将参数放在那里。
不同的调用约定以不同的方式推送参数。有些人可能会先推送第一个参数,有些人可能会最后推送第一个参数。或者有些人可能将参数保存在寄存器中,根本不推送它。
通过指定调用约定,您告诉编译器如何推送参数。