Pergunta

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

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

Eu estava confuso quanto ao que esta WINAPI identificador foi e encontrado:

#define WINAPI      __stdcall

O que isso faz? Estou confuso por este ter algo em tudo depois de um tipo de retorno. O que é __stdcall para? O que significa quando há algo entre o nome do tipo de retorno e função?

Foi útil?

Solução

__stdcall é a convenção de chamada usada para a função. Isto diz o compilador as regras que se aplicam para configurar a pilha, empurrando argumentos e obtendo um valor de retorno.

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

Wikipedia abrange a .

É importante, principalmente quando você está chamando uma função fora do seu código (por exemplo, uma API OS) ou o sistema operacional está chamando você (como é o caso aqui com WinMain). Se o compilador não sabe a convenção de chamada correta, então você provavelmente irá obter acidentes muito estranhos como a pilha não serão geridos corretamente.

Outras dicas

C ou C ++ em si não definir os identificadores. Eles são extensões do compilador e ficar para certas convenções de chamada. Que determina onde colocar argumentos, em que ordem, onde a função chamada vai encontrar o endereço de retorno, e assim por diante. Por exemplo, __fastcall meios que os argumentos de funções são passados ??mais registros.

O Wikipedia artigo fornece uma visão geral das diferentes convenções de chamada descobriu lá.

As respostas até agora ter coberto os detalhes, mas se você não pretende cair para montagem, então tudo que você tem que saber é que tanto o chamador e o receptor deve usar a mesma convenção de chamada, caso contrário você vai obter erros que são difíceis de encontrar.

Eu concordo que todas as respostas até agora estão corretas, mas aqui está a razão. compiladores da Microsoft C e C ++ fornecer várias convenções de chamada para (destinados) a velocidade de chamadas de função dentro de funções de um aplicativo C e C ++. Em cada caso, o chamador e chamado deve concordar em que convenção de chamada para uso. Agora, o próprio Windows oferece funções (APIs), e aqueles que já foram compilados, então quando você chamá-los você deve estar de acordo com eles. Todas as chamadas para APIs do Windows e chamadas de retorno a partir do Windows APIs, deve usar a convenção __stdcall.

Tem a ver com a forma como a função é called- basicamente a ordem em que as coisas são colocadas na pilha e que é responsável pela limpeza.

Aqui está a documentação, mas isso não significa muito menos que você compreender a primeira parte:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx

__ stdcall é usado para colocar os argumentos da função na pilha. Após a conclusão da função que desaloca automaticamente a memória. Isto é utilizado para argumentos fixos.

void __stdcall fnname ( int, int* )
{
    ...
}

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

Aqui, o fnname tem argumentos que empurram diretamente na pilha.

Eu nunca tive que usar isso antes, até hoje. É porque no meu código que estou usando multi-threadding ea API de multi-threading que estou usando é as janelas um (_beginthreadex).

Para iniciar o fio:

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

A função ExecuteCommand deve usar o __stdcall palavra-chave na assinatura do método para que beginthreadex chamá-lo:

unsigned int __stdcall Scene::ExecuteCommand(void* command)
{
    return system(static_cast<char*>(command));
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top