Что такое __stdcall?
Я изучаю программирование Win32, а прототип WinMain
выглядит так:
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE prev_instance, PSTR cmd_line, int cmd_show )
Я был в замешательстве относительно того, для чего был найден и найден этот идентификатор WINAPI
:
#define WINAPI __stdcall
Что это делает? Я смущен тем, что у вас что-то появилось после типа возврата. Для чего __stdcall
? Что это означает, что есть что-то между типом возвращаемого значения и именем функции?
Ответы
Ответ 1
__stdcall
- это вызов, используемый для функции. Это сообщает компилятору правила, которые применяются для настройки стека, нажатия аргументов и получения возвращаемого значения.
Существует ряд других условных соглашений, __cdecl
, __thiscall
, __fastcall
и чудесно названный __naked
. __stdcall
- стандартное соглашение о вызовах для системных вызовов Win32.
Википедия описывает подробности.
Это в первую очередь имеет значение, когда вы вызываете функцию вне вашего кода (например, API OS), или OS вызывает вас (как в случае с WinMain). Если компилятор не знает правильного соглашения о вызовах, вы, вероятно, получите очень странные сбои, так как стеки будут неправильно управляться.
Ответ 2
C или сам С++ не определяют эти идентификаторы. Они являются расширениями компилятора и поддерживают определенные соглашения о вызовах. Это определяет, где поставить аргументы, в каком порядке, где вызываемая функция найдет обратный адрес и т.д. Например, __fastcall означает, что аргументы функций передаются через регистры.
Статья Википедии содержит обзор различных вызовов, найденных там.
Ответ 3
Ответы до сих пор охватывали детали, но если вы не собираетесь сбрасывать на сборку, то все, что вам нужно знать, это то, что и вызывающий, и вызываемый должны использовать одно и то же соглашение о вызовах, иначе вы получить ошибки, которые трудно найти.
Ответ 4
Я согласен, что все ответы до сих пор верны, но вот причина. Компиляторы Microsoft C и С++ предоставляют различные соглашения о вызовах для (предполагаемой) скорости вызовов функций в приложениях C и С++. В каждом случае вызывающий и вызываемый должны согласовать, какое соглашение о вызове использовать. Теперь сама Windows предоставляет функции (API), и они уже скомпилированы, поэтому, когда вы их вызываете, вы должны соответствовать им. Любые вызовы API Windows и обратные вызовы из API Windows должны использовать соглашение __stdcall.
Ответ 5
Посмотрите:
http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx
Ответ 6
Это связано с тем, как называется функция - в основном, порядок, в котором вещи помещаются в стек и кто отвечает за очистку.
Здесь документация, но это мало значит, если вы не понимаете первую часть:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx
Ответ 7
__ stdcall используется для размещения аргументов функции в стеке.
После завершения функции она автоматически освобождает память.
Это используется для фиксированных аргументов.
void __stdcall fnname ( int, int* )
{
...
}
int main()
{
CreateThread ( NULL, 0, fnname, int, int*...... )
}
Здесь fnname имеет аргументы, которые он прямо вставляет в стек.
Ответ 8
Мне никогда не приходилось использовать это до сегодняшнего дня. Это потому, что в моем коде я использую многопоточность, а многопоточный API, который я использую, - это окна один (_beginthreadex).
Чтобы начать поток:
_beginthreadex(NULL, 0, ExecuteCommand, currCommand, 0, 0);
Функция ExecuteCommand ДОЛЖНА использовать ключевое слово __stdcall в сигнатуре метода, чтобы beginthreadex называет это:
unsigned int __stdcall Scene::ExecuteCommand(void* command)
{
return system(static_cast<char*>(command));
}