programing tip

__stdcall은 무엇입니까?

itbloger 2020. 6. 22. 08:04
반응형

__stdcall은 무엇입니까?


Win32 프로그래밍에 대해 배우고 있으며 WinMain프로토 타입은 다음과 같습니다.

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

WINAPI식별자가 무엇인지 발견하고 혼란 스러웠습니다 .

#define WINAPI      __stdcall

이것은 무엇을 하는가? 나는 이것이 리턴 타입 후에 무언가를 갖는 것에 혼란스러워합니다. 무엇입니까 __stdcall? 반환 유형과 함수 이름 사이에 무언가가있을 때 무엇을 의미합니까?


__stdcall함수에 사용되는 호출 규칙입니다. 이는 컴파일러에게 스택 설정, 인수 푸시 및 반환 값 가져 오기에 적용되는 규칙을 알려줍니다.

다른 호출 규칙의 숫자가 있습니다, __cdecl, __thiscall, __fastcall그리고 멋지고 이름 __naked. __stdcallWin32 시스템 호출에 대한 표준 호출 규칙입니다.

Wikipedia에서 자세한 내용을 다룹니다 .

코드 외부에서 함수 (예 : OS API)를 호출하거나 OS에서 사용자를 호출 할 때 (WinMain의 경우와 같이) 주로 중요합니다. 컴파일러가 올바른 호출 규칙을 모르면 스택이 올바르게 관리되지 않으므로 매우 이상한 충돌이 발생할 수 있습니다.


C 또는 C ++ 자체는 이러한 식별자를 정의하지 않습니다. 그것들은 컴파일러 확장이며 특정 호출 규칙을 나타냅니다. 호출 된 함수가 리턴 주소를 찾는 위치 등을 순서대로 배치 할 위치를 결정합니다. 예를 들어 __fastcall은 함수의 인수가 레지스터를 통해 전달됨을 의미합니다.

위키 백과 기사 가 발견 다른 호출 규칙에 대한 개요를 제공합니다.


지금까지의 답변은 세부 사항을 다루었지만 어셈블리로 드롭하지 않으려면 발신자와 수신자 모두 동일한 호출 규칙을 사용해야한다는 것만 알면됩니다. 그렇지 않으면 버그가 발생합니다. 찾기 어렵다.


지금까지의 모든 답변이 정확하지만 여기에 이유가 있습니다. Microsoft의 C 및 C ++ 컴파일러는 응용 프로그램의 C 및 C ++ 함수 내에서 의도 된 속도의 함수 호출에 대한 다양한 호출 규칙을 제공합니다. 각각의 경우, 호출자와 호출 수신자는 사용할 호출 규칙에 동의해야합니다. 이제 Windows 자체는 함수 (API)를 제공하며 이미 컴파일 된 기능이므로 호출 할 때이를 준수해야합니다. Windows API에 대한 모든 호출 및 Windows API의 콜백은 __stdcall 규칙을 사용해야합니다.


살펴보십시오 :

http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx


함수가 호출되는 방식과 관련이 있습니다. 기본적으로 스택에 물건이 쌓이는 순서와 정리 담당자입니다.

다음은 설명서이지만 첫 번째 부분을 이해하지 않으면 의미가 없습니다.
http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx


__stdcall은 함수 인수를 스택에 넣는 데 사용됩니다. 기능이 완료된 후 자동으로 메모리 할당을 해제합니다. 고정 인수에 사용됩니다.

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

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

여기 fnname 에는 스택으로 직접 푸시되는 인수가 있습니다.


나는 오늘까지 이것을 사용하지 않았다. 내 코드에서 멀티 스레딩을 사용하고 있으며 사용중인 멀티 스레딩 API가 Windows (_beginthreadex)이기 때문입니다.

스레드를 시작하려면

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

ExecuteCommand를 기능은 반드시 beginthreadex가 전화를 위해서는 메소드 서명에서 __stdcall 키워드를 사용 :

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

참고 URL : https://stackoverflow.com/questions/297654/what-is-stdcall

반응형