gpt4 book ai didi

c++ - __stdcall 的优点/用途是什么?

转载 作者:行者123 更新时间:2023-12-01 19:10:29 24 4
gpt4 key购买 nike

在发布这个问题之前,我已经阅读了一些文档,SO answers并观看了一些视频来了解__stdcall 。到目前为止,我已经理解这是一个调用约定,并指定将参数从右向左推送到堆栈上。这也表示何时清除堆栈。

但我仍然无法理解优势和应该使用__stdcall的情况.

我遇到了以下代码,该代码在 OPC-UA 客户端关闭时被调用。我发现这应该遵循 __stdcall调用约定但为什么呢?如果 __stdcall 可能会发生什么没有指定以下方法?

OpcUa_StatusCode __stdcall opcua_client::onShutdownMessage(OpcUa_Handle hApplication, OpcUa_Handle hSession, OpcUa_String strShutdownMessage, void* extraParam)
{
opcua_client* pOpcClient = NULL;
if (extraParam)
{
try
{
pOpcClient = qobject_cast <opcua_client*>((QObject*)extraParam);
throw(55);
}
catch (int exeption)
{

}
}

OpcUa_StatusCode uStatus = OpcUa_Good;

QString strShutDownMsg = QString::fromUtf8(OpcUa_String_GetRawString(&strShutdownMessage));
bool bOK;
OpcUa_StatusCode uClientLibStatus = uClientLibStatus = strShutDownMsg.toUInt(&bOK, 16);

if (pOpcClient)
{
if (uClientLibStatus > 0)
pOpcClient->process_onShutdownMessage(uClientLibStatus);
}
else
{
return uStatus;
}

return uStatus;
}

最佳答案

调用者必须遵循函数调用约定。如果存在,则必须有该函数的某个调用者假设必须以特定方式调用它。当您有回调函数时,这通常很重要。

除此之外,与 cdecl 相比,stdcall 旨在通过将参数清理代码从调用者移动到被调用者(可以使用 ret imm16 来减少代码大小) x86)。

这是针对 IA-32 架构的旧微优化。 MSVC 在其他架构上也接受 __stdcall 关键字,但它 doesn't do anything there .

检查这个例子:

__declspec(noinline) int sum(int a, int b)
{
return a + b;
}

int add1(int a)
{
return sum(a, 1);
}

MSVC 将其编译为:

int sum(int,int) PROC
mov eax, DWORD PTR _a$[esp-4]
add eax, DWORD PTR _b$[esp-4]
ret 0 ; this instruction will be replaced
int sum(int,int) ENDP

int add1(int) PROC
push 1
push DWORD PTR _a$[esp]
call int sum(int,int)
add esp, 8 ; this instruction will be removed
ret 0
int add1(int) ENDP

以及带有 stdcall 的版本:

__declspec(noinline) int __stdcall sum(int a, int b)
{
return a + b;
}

int add1(int a)
{
return sum(a, 1);
}

编译为:

int sum(int,int) PROC
mov eax, DWORD PTR _a$[esp-4]
add eax, DWORD PTR _b$[esp-4]
ret 8 ; 0 argument replaced with 8
int sum(int,int) ENDP

int add1(int) PROC
push 1
push DWORD PTR _a$[esp]
call int sum(int,int)
ret 0 ; extra instruction is missing here
int add1(int) ENDP

请注意第二个示例如何使用 ret 8 并且调用者没有额外的 add esp, 8

关于c++ - __stdcall 的优点/用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58321528/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com