Что такое stdcall?

Я изучаю Программирование Win32 и WinMain прототип выглядит так:

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

Я был смущен тем, что это WINAPI идентификатор был и нашел:

#define WINAPI      __stdcall

что это значит? Я смущен тем, что у этого есть что-то вообще после типа возврата. Что такое __stdcall для чего? Что это значит, когда есть что-то между типом возврата и именем функции?

8 ответов


__stdcall - Это соглашение о вызовах для функции. Это сообщает компилятору правила, которые применяются для настройки стека, нажатия аргументов и получения возвращаемого значения.

существует ряд других соглашений о вызовах,__cdecl, __thiscall, __fastcall и чудесно названный __naked. __stdcall является стандартным соглашением о вызовах для системных вызовов Win32.

Википедия охватывает подробности.

это в первую очередь имеет значение, когда вы вызываем функцию вне вашего кода (например, API ОС) или ОС вызывает вас (как в случае с WinMain). Если компилятор не знает правильного соглашения о вызове, вы, вероятно, получите очень странные сбои, поскольку стек не будет управляться правильно.


C или c++ сами по себе не определяют эти идентификаторы. Они являются расширениями компилятора и соответствуют определенным соглашениям о вызовах. Это определяет, куда ставить аргументы, в каком порядке, где вызываемая функция найдет обратный адрес и так далее. Например, __fastcall означает, что аргументы функций передаются через регистры.

на Статья В Википедии предоставляет обзор различных соглашений о вызовах, найденных там.


ответы до сих пор охватывали детали, но если вы не собираетесь опускаться до сборки, то все, что вам нужно знать, это то, что и вызывающий, и вызываемый должны использовать одно и то же соглашение о вызове, иначе вы получите ошибки, которые трудно найти.


Я согласен, что все ответы, которые до сих пор верны, но вот почему. Компиляторы Microsoft C и c++ предоставляют различные соглашения о вызовах для (предполагаемой) скорости вызовов функций в функциях C и C++ приложения. В каждом случае вызывающий абонент и вызываемый абонент должны договориться о том, какое соглашение о вызове использовать. Теперь Windows сама предоставляет функции (API), и они уже были скомпилированы, поэтому, когда вы их вызываете, вы должны соответствовать им. Любые вызовы API Windows и обратные вызовы из API-интерфейсов Windows необходимо использовать соглашение __stdcall.



Это связано с тем, как вызывается функция - в основном порядок, в котором вещи помещаются в стек и кто отвечает за очистку.

вот документация, но это не значит много, если вы не понимаете первую часть:
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx


соглашение__stdcall используется для размещения аргументов в стеке. После завершения функции он автоматически освобождает память. Это используется для фиксированных аргументов.

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

int main()
{
    CreateThread ( NULL, 0, fnname, int, int*...... )
}
на fnname имеет args он сразу нажимает в стог.

мне никогда не приходилось использовать это до сегодняшнего дня. Это потому, что в моем коде я использую многопоточность, а многопоточный API, который я использую,-это windows one (_beginthreadex).

запустить поток:

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

функция ExecuteCommand должны используйте ключевое слово __stdcall в сигнатуре метода, чтобы beginthreadex мог его вызвать:

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