繁体   English   中英

何时使用调用约定

[英]When to use calling conventions

使用不同调用约定的关键因素是什么? 什么时候有人知道在不同的场合使用特定的调用约定,例如__cdecl__stdcall__fastcall

实例将是真正适用的。

大多数时候你不需要担心它。 通常你会使用__cdecl ,但这只是因为它是Visual C ++中的默认值。 但是,C ++成员函数在Visual C ++中默认使用__thiscall约定

一个(相当普遍的)情况,你真的不得不担心调用约定是当你将回调传递给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);

在这里,我们声明MyWndProc()作为具有__stdcall约定( CALLBACK#define倒是为__stdcall )。 这是必需的,因为操作系统期望lpfnWndProc指向使用CALLBACK约定WNDPROC

几乎每个接受回调的Windows API函数都要求回调函数使用__stdcall约定,并且由于__cdecl通常是默认值,因此必须使其显式(您可以使用CALLBACK进行窗口过程)。

这非常重要,因为如果操作系统尝试调用非__stdcall函数,则可能发生堆栈损坏。 不幸的是,有足够的人弄错了Windows实际上会检查调用约定不匹配的窗口程序

虽然传递给WinAPI函数的回调函数需要__stdcall ,但接受可变数量参数的函数必须使用__cdecl调用约定,因为只有调用者才知道如何正确地从堆栈中弹出可变数量的参数。 由于__cdecl通常是默认值,因此您不需要为接受可变数量参数的函数显式指定__cdecl

我个人还没有找到__fastcall的用途,虽然我确信有人有。

只有在与托管代码交互时, __clrcall才有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM