DirectX11 - WinMain 함수

Sungsik Bae·2024년 1월 14일

DirectX11

목록 보기
1/6
post-thumbnail

WinMain 함수 분석

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{

}

APIENTRY와 WINAPI의 차이점이 무엇일까 찾아보았다.

#define APIENTRY    WINAPI

정의를 찾아보니 위와 같다.

위의 참고 사이트StackOverFlow에서도 찾아본 결과 정말로 같은 의미로 사용되는 거 같다.

그렇다면 WINAPI는 뭘까?

#define WINAPI      __stdcall

라고 정의되어 있다.

_stdcall은 또 뭐야? 찾아봅시다.

Calling conventions(호출 규약)

Microsoft 공식 문서를 보면 인수 전달이나 함수가 반환되는 방법을 정하는 것 같다.

The topics on this subject explain the differences between the calling conventions, how arguments are passed, and how values are returned by functions. They also discuss naked function calls, an advanced feature that enables you to write your own prolog and epilog code.

대표적으로 아래의 3가지가 제일 많이 사용되는 것 같다.

KeywordStack cleanupParameter passing
__cdeclCallerPushes parameters on the stack, in reverse order (right to left)
__stdcallCalleePushes parameters on the stack, in reverse order (right to left)
__fastcallCalleeStored in registers, then pushed on stack

Caller는 함수 호출자 Callee는 함수 피호출자

아래는 참고 사이트 내용을 정리한 것이다.

  • cdecl
    • 가장 많이 사용되는 호출 규약
    • 함수 호출 규약을 입력하지 않으면 cdecl이 기본값으로 적용됨
    • 파라미터를 오른쪽에서 왼쪽으로 stack에 push함
    • 함수가 종료되면 caller는 스택을 정리함
  • stdcall
    • cdecl과 비슷한 호출 규약
    • 파라미터를 오른쪽에서 왼쪽으로 stack에 push함
    • Window API에 대한 기본 호출 규약
    • 함수가 종료되면 callee가 직접 스택을 정리함
  • fastcall
    - 컴파일러마다 호출 규약이 다르나 보통 비슷함
    - 보통 2개의 인자들을 각 EDX, ECX 레지스터에 놓고 나머지 인자들을 오른쪽에서 왼쪽으로 메모리에 로드함
    - 필요시 호출 함수는 일반적으로 스택을 정리
    - 코드를 스택에 많이 push 하지 않아도 되므로 다른 호출 규약보다 빠름
    추가 참고 사이트

중간에 너무 딴 길로 샌 느낌이 들긴 하지만 새로운 것을 배웠다. 함수를 호출하는 것에도 다양한 방식이 있으며 Window함수는 __stdcall를 사용한 다는 것이다.

__stdcall를 왜 사용하는지를 알아보지 않을 수가 없겠군 :)
찾아보니 확실하지는 않지만, 매개인자의 수가 고정되어 있어 stackframe에서 삽입, 삭제가 일정하기 때문에 Callee가 스탭 삽입, 삭제, 정리를 하기 용이하기 때문이라고 한다.

이 부분은 솔직히 막 와닿지 않아서 나중에 추가로 찾아봐야 할 듯

cat-confused

파라미터 분석

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{

}

파라미터를 보자마자 _In_, _In_opt_ 같은 새로운 것이 또 눈에 띈다.
이건 또 무엇일까..

SAL이란 무엇일까

Microsoft 공식 문서는 이렇게 정리하고 있다.

SAL이란 마이크로소프트 소스 코드 주석 언어(source-code annotation language) 라고 한다. 이렇게 보면 무슨 뜻인지 잘 모르겠다.. 추측하기로는 소스 코드 상에서 주석과 같은 역할을 하는 것 같다. _In_은 Input 받는 파라미터라는 뜻인가?

SAL에는 다음과 같은 종류가 있나보다.

CategoryParameter AnnotationDescription
Input to called function_In_Data is passed to the called function, and is treated as read-only.
Input to called function, and output to caller_Inout_Usable data is passed into the function and potentially is modified.
Output to caller_Out_The caller only provides space for the called function to write to. The called function writes data into that space.
Output of pointer to caller_OutPtr_Like Output to caller. The value that's returned by the called function is a pointer.

Optional를 제공해주는 것들도 있는 것 같은데, 위의 링크를 참조하면 될 거 같다.

결론은 내가 예상했던 것과 일치했다. 와 정말 놀라워요

otter-shocked

또 딴 길로 새어버렸다. 이제 제대로 파라미터에 대해 알아봐야겠다.

  • HINSTANCE hInstance : 응용 프로그램의 HANDLE을 의미한다. (HANDLE은 OS에서 제공한다.)
  • HINSTANCE hPrevInstance : 파라미터의 이름과 같이 이전의 응용 프로그램의 HANDLE을 의미한다.
  • LPWSTR lpCmdLine : 명령줄 인수가 UNICODE로 들어옵니다.
  • int nCmdShow : 응용 프로그램 창이 최소화, 최대화 또는 정상적으로 표시되는지 여부를 나타내는 Flag값이다.

드디어 파라미터까지 다 알아보았으니 WinMain함수에 대해 알아보았다고 할 수 있겠다.

profile
Game Developer

0개의 댓글