Ich lerne etwas über Win32-Programmierung und der WinMain
Prototyp sieht folgendermaßen aus:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
Ich war verwirrt darüber, wofür diese WINAPI
Kennung gedacht war und fand:
#define WINAPI __stdcall
Was macht das? Ich bin verwirrt darüber, dass ich nach einem Rückgabetyp überhaupt etwas habe. Wofür ist __stdcall
? Was bedeutet es, wenn zwischen dem Rückgabetyp und dem Funktionsnamen etwas liegt?
c
winapi
calling-convention
stdcall
Tristan Havelick
quelle
quelle
s verwenden, um das alberne (und kontraproduktive - Beispiel) 6-Zeichen-Minimum zu umgehen.Antworten:
__stdcall
ist die für die Funktion verwendete Aufrufkonvention. Dies teilt dem Compiler die Regeln mit, die für das Einrichten des Stapels, das Übertragen von Argumenten und das Abrufen eines Rückgabewerts gelten.Es gibt eine Reihe von anderen Aufrufkonventionen,
__cdecl
,__thiscall
,__fastcall
und die wunderbar benannt__declspec(naked)
.__stdcall
ist die Standardaufrufkonvention für Win32-Systemaufrufe.Wikipedia behandelt die Details .
Dies ist in erster Linie wichtig, wenn Sie eine Funktion außerhalb Ihres Codes aufrufen (z. B. eine Betriebssystem-API) oder das Betriebssystem Sie aufruft (wie dies hier bei WinMain der Fall ist). Wenn der Compiler die richtige Aufrufkonvention nicht kennt, kommt es wahrscheinlich zu sehr seltsamen Abstürzen, da der Stack nicht richtig verwaltet wird.
quelle
C oder C ++ selbst definieren diese Bezeichner nicht. Sie sind Compiler-Erweiterungen und stehen für bestimmte Aufrufkonventionen. Dies bestimmt, wo Argumente in welcher Reihenfolge abgelegt werden sollen, wo die aufgerufene Funktion die Rücksprungadresse findet und so weiter. Zum Beispiel bedeutet __fastcall, dass Argumente von Funktionen über Register übergeben werden.
Der Wikipedia-Artikel bietet einen Überblick über die verschiedenen dort gefundenen Anrufkonventionen.
quelle
Die bisherigen Antworten haben die Details abgedeckt. Wenn Sie jedoch nicht beabsichtigen, zur Montage zu wechseln, müssen Sie lediglich wissen, dass sowohl der Anrufer als auch der Angerufene dieselbe Anrufkonvention verwenden müssen, da sonst Fehler auftreten sind schwer zu finden.
quelle
Ich stimme zu, dass alle bisherigen Antworten richtig sind, aber hier ist der Grund. Die C- und C ++ - Compiler von Microsoft bieten verschiedene Aufrufkonventionen für die (beabsichtigte) Geschwindigkeit von Funktionsaufrufen innerhalb der C- und C ++ - Funktionen einer Anwendung. In jedem Fall müssen sich Anrufer und Angerufene darauf einigen, welche Anrufkonvention verwendet werden soll. Jetzt bietet Windows selbst Funktionen (APIs), die bereits kompiliert wurden. Wenn Sie sie aufrufen, müssen Sie sie also anpassen. Alle Aufrufe von Windows-APIs und Rückrufe von Windows-APIs müssen die Konvention __stdcall verwenden.
quelle
Schauen Sie sich an:
http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx
quelle
Es hat damit zu tun, wie die Funktion aufgerufen wird - im Grunde die Reihenfolge, in der die Dinge auf den Stapel gelegt werden und wer für die Bereinigung verantwortlich ist.
Hier ist die Dokumentation, aber sie bedeutet nicht viel, es sei denn, Sie verstehen den ersten Teil:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
quelle
__stdcall wird verwendet, um die Funktionsargumente in den Stapel zu legen. Nach Abschluss der Funktion wird der Speicher automatisch freigegeben. Dies wird für feste Argumente verwendet.
Hier hat der fnname Argumente, die er direkt in den Stapel schiebt.
quelle
Ich musste das bis heute noch nie benutzen. Das liegt daran, dass ich in meinem Code Multithreadding verwende und die von mir verwendete Multithreading-API die Windows-API (_beginthreadex) ist.
So starten Sie den Thread:
Die ExecuteCommand-Funktion MUSS das Schlüsselwort __stdcall in der Methodensignatur verwenden, damit Beginthreadex es aufruft:
quelle