Qu’est-ce que __stdcall?

WinMain la programmation Win32 et le prototype WinMain ressemble à:

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

J’étais confus quant à la WINAPI cet identifiant WINAPI et trouvé:

 #define WINAPI __stdcall 

Qu’est-ce que cela fait? Je suis désorienté d’avoir quelque chose après un type de retour. Qu’est-ce que __stdcall ? Qu’est-ce que cela signifie quand il y a quelque chose entre le type de retour et le nom de la fonction?

__stdcall est la convention d’appel utilisée pour la fonction. Cela indique au compilateur les règles qui s’appliquent à la configuration de la stack, en plaçant des arguments et en obtenant une valeur de retour.

Il existe un certain nombre d’autres conventions d’appel, __cdecl , __thiscall , __fastcall et le nom merveilleusement bien nommé __naked . __stdcall est la convention d’appel standard pour les appels système Win32.

Wikipedia couvre les détails .

Cela concerne principalement lorsque vous appelez une fonction en dehors de votre code (par exemple, une API OS) ou que le système d’exploitation vous appelle (comme c’est le cas ici avec WinMain). Si le compilateur ne connaît pas la convention d’appel correcte, vous obtiendrez probablement des accidents très étranges car la stack ne sera pas gérée correctement.

C ou C ++ lui-même ne définissent pas ces identificateurs. Ce sont des extensions du compilateur et représentent certaines conventions d’appel. Cela détermine où placer les arguments, dans quel ordre, où la fonction appelée trouvera l’adresse de retour, etc. Par exemple, __fastcall signifie que les arguments des fonctions sont passés sur des registres.

L’ article de Wikipedia donne un aperçu des différentes conventions d’appel trouvées.

Les réponses à ce jour couvrent les détails, mais si vous n’avez pas l’intention de vous rendre à l’assemblage, tout ce que vous devez savoir, c’est que l’appelant et l’appelé doivent utiliser la même convention d’appel. sont difficiles à trouver.

Je suis d’accord que toutes les réponses sont correctes, mais voici la raison. Les compilateurs C et C ++ de Microsoft fournissent diverses conventions d’appel pour la vitesse (prévue) des appels de fonctions dans les fonctions C et C ++ d’une application. Dans chaque cas, l’appelant et l’appelé doivent s’entendre sur la convention d’appel à utiliser. Maintenant, Windows lui-même fournit des fonctions (API), et celles-ci ont déjà été compilées. Par conséquent, lorsque vous les appelez, vous devez vous y conformer. Tous les appels aux API Windows et les rappels des API Windows doivent utiliser la convention __stdcall.

Cela a à voir avec comment la fonction est appelée – essentiellement l’ordre dans lequel les choses sont placées sur la stack et qui est responsable du nettoyage.

Voici la documentation, mais cela ne veut pas dire grand chose à moins de comprendre la première partie:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx

__stdcall est utilisé pour placer les arguments de la fonction dans la stack. Une fois la fonction terminée, la mémoire est automatiquement libérée. Ceci est utilisé pour les arguments fixes.

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

Ici, le nom de fichier a des arguments qu’il insère directement dans la stack.

Je n’ai jamais eu à l’utiliser avant aujourd’hui. C’est parce que dans mon code j’utilise le multi-threading et l’API multi-threading que j’utilise est celle de Windows (_beginthreadex).

Pour démarrer le fil:

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

La fonction ExecuteCommand DOIT utiliser le mot clé __stdcall dans la signature de la méthode pour que beginthreadex l’appelle:

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