O que é __stdcall?

Estou aprendendo sobre programação Win32, e o protótipo WinMain parece com:

 int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show ) 

Eu estava confuso sobre o que era esse identificador WINAPI e achei:

 #define WINAPI __stdcall 

O que isso faz? Estou confuso por isso ter algo depois de um tipo de retorno. O que é __stdcall para? O que significa quando há algo entre o tipo de retorno e o nome da function?

__stdcall é a convenção de chamada usada para a function. Isso informa ao compilador as regras que se aplicam à configuração da pilha, enviando argumentos e obtendo um valor de retorno.

Há uma série de outras convenções de chamadas, __cdecl , __thiscall , __fastcall e o maravilhosamente chamado __naked . __stdcall é a convenção de chamada padrão para chamadas do sistema Win32.

Wikipedia cobre os detalhes .

Principalmente importa quando você está chamando uma function fora do seu código (por exemplo, uma API do sistema operacional) ou o sistema operacional está chamando você (como é o caso aqui com WinMain). Se o compilador não conhecer a convenção de chamada correta, você provavelmente terá falhas muito estranhas, pois a pilha não será gerenciada corretamente.

C ou C ++ em si não definem esses identificadores. Eles são extensões de compilador e representam certas convenções de chamada. Isso determina onde colocar argumentos, em qual ordem, onde a function chamada encontrará o endereço de retorno e assim por diante. Por exemplo, __fastcall significa que os argumentos das funções são passados ​​pelos registradores.

O artigo da Wikipedia fornece uma visão geral das diferentes convenções de chamadas encontradas por aí.

As respostas até agora cobriram os detalhes, mas se você não pretende descer para a assembly, então tudo o que você precisa saber é que tanto o chamador quanto o chamado precisam usar a mesma convenção de chamada, senão você obterá erros são difíceis de encontrar.

Eu 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) das chamadas de function dentro das funções C e C ++ de um aplicativo. Em cada caso, o chamador e o chamado devem concordar em qual convenção de chamada usar. Agora, o próprio Windows fornece funções (APIs) e elas 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.

Tem a ver com como a function é 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/pt-br/library/zxk0tw93.aspx

__stdcall é usado para colocar os argumentos da function na pilha. Após a conclusão da function, ela desaloca automaticamente a memory. Isso é usado para argumentos fixos.

 void __stdcall fnname ( int, int* ) { ... } int main() { CreateThread ( NULL, 0, fnname, int, int*...... ) } 

Aqui o fnname tem args que empurram diretamente para a pilha.

Eu nunca tive que usar isso antes até hoje. É porque no meu código estou usando multi-threading e a API multi-threading que estou usando é o windows one (_beginthreadex).

Para iniciar o segmento:

 _beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0); 

A function ExecuteCommand DEVE usar a palavra-chave __stdcall na assinatura do método para que o beginthreadex a chame:

 unsigned int __stdcall Scene::ExecuteCommand(void* command) { return system(static_cast(command)); }