Dav*_*eng 6 calling-convention visual-c++
使用不同调用约定的关键因素是什么?当没有人知道使用特定的调用约定,如__cdecl或__stdcall或__fastcall在不同的场合.
实例将是真正适用的.
In *_*ico 13
大多数时候你不需要担心它.通常你会使用__cdecl,但只是因为这是Visual C++中的默认值.但是,C++成员函数__thiscall在Visual C++中默认使用约定
一个(相当普遍的)情况,你真的不得不担心调用约定是当你将回调传递给API函数时,就像在Windows API中那样:
// CALLBACK is #define'd as __stdcall
LRESULT CALLBACK MyWndProc(HWND hwnd, UINT msg
WPARAM wParam, LPARAM lParam);
// ...
windowClass.lpfnWndProc = &MyWndProc;
::RegisterClass(&windowClass);
Run Code Online (Sandbox Code Playgroud)
在这里,我们声明MyWndProc()具有__stdcall约定(CALLBACK是#define'd as __stdcall).这是必需的,因为操作系统期望lpfnWndProc指向a WNDPROC,它使用CALLBACK约定.
几乎每个接受回调的Windows API函数都要求回调函数使用__stdcall约定,并且由于__cdecl通常是默认值,因此必须将其显式化(您将使用CALLBACK窗口过程).
这非常重要,因为如果操作系统尝试调用非__stdcall函数,则可能发生堆栈损坏.不幸的是,有足够的人弄错了Windows实际上会检查调用约定不匹配的窗口程序.
虽然__stdcall需要传递给WinAPI的函数回调函数,接受可变数量的参数必须使用函数__cdecl调用约定,因为只有调用者将知道如何正确地弹出可变数量的参数堆栈.由于__cdecl通常是默认值,因此您无需为__cdecl接受可变数量参数的函数显式指定.
我个人没有找到用途__fastcall,虽然我确信有人.
__clrcall 只有在与托管代码交互时才有意义.
| 归档时间: |
|
| 查看次数: |
982 次 |
| 最近记录: |