Estou aprendendo sobre programação Win32, e o WinMain
protótipo se parece com:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
Fiquei confuso sobre o que WINAPI
era esse identificador e encontrei:
#define WINAPI __stdcall
O que isso faz? Estou confuso por ter alguma coisa depois de um tipo de retorno. Para que serve __stdcall
? O que significa quando há algo entre o tipo de retorno e o nome da função?
c
winapi
calling-convention
stdcall
Tristan Havelick
fonte
fonte
s para contornar o mínimo bobo (e contraproducente - neste caso) de 6 caracteres.Respostas:
__stdcall
é a convenção de chamada usada para a função. Isso informa ao compilador as regras que se aplicam para configurar a pilha, enviar argumentos e obter um valor de retorno.Há uma série de outras convenções de chamada,
__cdecl
,__thiscall
,__fastcall
e maravilhosamente nomeado__declspec(naked)
.__stdcall
é a convenção de chamada padrão para chamadas do sistema Win32.A Wikipedia cobre os detalhes .
É importante principalmente quando você está chamando uma função fora do seu código (por exemplo, uma API do sistema operacional) ou se o sistema operacional está chamando você (como é o caso do WinMain). Se o compilador não souber a convenção de chamada correta, provavelmente ocorrerá falhas muito estranhas, pois a pilha não será gerenciada corretamente.
fonte
C ou C ++ em si não definem esses identificadores. Eles são extensões do compilador e representam certas convenções de chamada. Isso determina onde colocar argumentos, em que ordem, onde a função chamada encontrará o endereço de retorno e assim por diante. Por exemplo, __fastcall significa que argumentos de funções são passados por registradores.
O artigo da Wikipedia fornece uma visão geral das diferentes convenções de chamadas encontradas lá.
fonte
As respostas até agora cobriram os detalhes, mas se você não pretende ir para a montagem, tudo o que você precisa saber é que o chamador e o destinatário devem usar a mesma convenção de chamada; caso contrário, você receberá bugs que são difíceis de encontrar.
fonte
Concordo que todas as respostas até agora estão corretas, mas aqui está a razão. Os compiladores C e C ++ da Microsoft fornecem várias convenções de chamada para a velocidade (pretendida) de chamadas de função nas funções C e C ++ de um aplicativo. Em cada caso, o chamador e o destinatário devem concordar com qual convenção de chamada usar. Agora, o próprio Windows fornece funções (APIs) e essas já foram compiladas; portanto, quando você as chama, deve estar em conformidade com elas. Quaisquer chamadas para APIs do Windows e retornos de chamada das APIs do Windows devem usar a convenção __stdcall.
fonte
Dê uma olhada em:
http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx
fonte
Tem a ver com a forma como a função é chamada - basicamente a ordem em que as coisas são colocadas na pilha e quem é responsável pela limpeza.
Aqui está a documentação, mas isso não significa muito, a menos que você entenda a primeira parte:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
fonte
__stdcall é usado para colocar os argumentos da função na pilha. Após a conclusão da função, ela desaloca automaticamente a memória. Isso é usado para argumentos fixos.
Aqui o nome fn tem argumentos que ele envia diretamente para a pilha.
fonte
Eu nunca tive que usar isso antes até hoje. É porque no meu código eu estou usando multiencadeamento e a API de multiencadeamento que eu estou usando é a do Windows (_beginthreadex).
Para iniciar o encadeamento:
A função ExecuteCommand DEVE usar a palavra-chave __stdcall na assinatura do método para o beginthreadex chamá-lo:
fonte