[엔진 소스 코드 분석] 1 - LaunchWindows.cpp

2025. 3. 26. 23:57·Unreal Engine/이것 저것

1. 프로그램의 시작점 WinMain

int32 WINAPI WinMain(_In_ HINSTANCE hInInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ char* pCmdLine, _In_ int32 nCmdShow)
{
	// LaunchWidnowsStartup으로부터 엔진 루프까지
	int32 Result = LaunchWindowsStartup(hInInstance, hPrevInstance, pCmdLine, nCmdShow, nullptr);
	// 종료 전 해야할 일 처리
	LaunchWindowsShutdown();
    	// 실행 결과 반환
	return Result;
}

 

2. 엔진 시작점 LaunchWindowsStartup

LAUNCH_API int32 LaunchWindowsStartup( HINSTANCE hInInstance, HINSTANCE hPrevInstance, char*, int32 nCmdShow, const TCHAR* CmdLine )
{
	// 로깅을 위한 매크로 호출
	TRACE_BOOKMARK(TEXT("WinMain.Enter"));
    
    // 메모리 주소 취약점과 메모리 오류를 감지하기 위한 매크로가 선언된 경우의 처리
#if USING_ADDRESS_SANITISER
	__asan_set_error_report_callback(ASanErrorCallback);
#endif

	// Setup common Windows settings - 실행 인자 검증 및 Debug모드인 경우 메모리 누수 검출 활성화
	SetupWindowsEnvironment();

	int32 ErrorLevel			= 0;
	hInstance				= hInInstance;

	
	if (!CmdLine)
	{
		CmdLine = ::GetCommandLineW();

		// Attempt to process the command-line arguments using the standard Windows implementation
		// (This ensures behavior parity with other platforms where argc and argv are used.)
		if ( ProcessCommandLine() )
		{
			CmdLine = *GSavedCommandLine;
		}
	}

	// If we're running in unattended mode, make sure we never display error dialogs if we crash.
	if ( FParse::Param( CmdLine, TEXT("unattended") ) )
	{
		SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
	}

	if ( FParse::Param( CmdLine,TEXT("crashreports") ) )
	{
		GAlwaysReportCrash = true;
	}

	uint32 LogicalCoreAffinity = 0;
	uint32 PhysicalCoreAffinity = 0;
	FParse::Value(CmdLine, TEXT("-processaffinity="), LogicalCoreAffinity);
	FParse::Value(CmdLine, TEXT("-processaffinityphysical="), PhysicalCoreAffinity);

	if (LogicalCoreAffinity > 0)
	{
		FWindowsPlatformProcess::SetProcessAffinity(LogicalCoreAffinity, false);
	}
	else if (PhysicalCoreAffinity > 0)
	{
		FWindowsPlatformProcess::SetProcessAffinity(PhysicalCoreAffinity, true);
	}

	bool bNoExceptionHandler = FParse::Param(CmdLine,TEXT("noexceptionhandler"));
	(void)bNoExceptionHandler;

	bool bIgnoreDebugger = FParse::Param(CmdLine, TEXT("IgnoreDebugger"));
	(void)bIgnoreDebugger;

	bool bIsDebuggerPresent = FPlatformMisc::IsDebuggerPresent() && !bIgnoreDebugger;
	(void)bIsDebuggerPresent;

	// Using the -noinnerexception parameter will disable the exception handler within native C++, which is call from managed code,
	// which is called from this function.
	// The default case is to have three wrapped exception handlers 
	// Native: WinMain() -> Native: GuardedMainWrapper().
	// The inner exception handler in GuardedMainWrapper() catches crashes/asserts in native C++ code and is the only way to get the
	// correct callstack when running a 64-bit executable. However, XAudio2 sometimes (?) don't like this and it may result in no sound.
#ifdef _WIN64
	if ( FParse::Param(CmdLine,TEXT("noinnerexception")) || FApp::IsBenchmarking() || bNoExceptionHandler)
	{
		GEnableInnerException = false;
	}
#endif	

	// When we're running embedded, assume that the outer application is going to be handling crash reporting
#if UE_BUILD_DEBUG
	if (GUELibraryOverrideSettings.bIsEmbedded || !GAlwaysReportCrash)
#else
	if (GUELibraryOverrideSettings.bIsEmbedded || bNoExceptionHandler || (bIsDebuggerPresent && !GAlwaysReportCrash))
#endif
	{
		// Don't use exception handling when a debugger is attached to exactly trap the crash. This does NOT check
		// whether we are the first instance or not!
		ErrorLevel = GuardedMain( CmdLine );
	}
	else
	{
		// Use structured exception handling to trap any crashes, walk the the stack and display a crash dialog box.
#if !PLATFORM_SEH_EXCEPTIONS_DISABLED
		__try
#endif
 		{
			GIsGuarded = 1;
			// Run the guarded code.
			ErrorLevel = GuardedMainWrapper( CmdLine );
			GIsGuarded = 0;
		}
#if !PLATFORM_SEH_EXCEPTIONS_DISABLED
		__except( FPlatformMisc::GetCrashHandlingType() == ECrashHandlingType::Default
				? ( GEnableInnerException ? EXCEPTION_EXECUTE_HANDLER : ReportCrash(GetExceptionInformation()) )
				: EXCEPTION_CONTINUE_SEARCH )	
		{
			// Crashed.
			ErrorLevel = 1;
			if(GError)
			{
				GError->HandleError();
			}
			LaunchStaticShutdownAfterError();
			FPlatformMallocCrash::Get().PrintPoolsUsage();
			FPlatformMisc::RequestExit( true, TEXT("LaunchWindowsStartup.ExceptionHandler"));
		}
#endif
	}

	TRACE_BOOKMARK(TEXT("WinMain.Exit"));

	return ErrorLevel;
}

'Unreal Engine > 이것 저것' 카테고리의 다른 글

[강의] Haker UE5 소스코드 분석#1(게임 프레임워크) - 2.환경설정  (0) 2025.12.08
[Network] 채팅 프로그램 만들기  (0) 2025.03.17
게임 언패킹과 리타게팅, 그리고 머티리얼에 대하여 ( 1 )  (0) 2025.02.07
에디터에서 FVector 수정을 위한 UPROPERTY 사용  (0) 2025.02.03
유튜브 레퍼런스  (0) 2025.02.01
'Unreal Engine/이것 저것' 카테고리의 다른 글
  • [강의] Haker UE5 소스코드 분석#1(게임 프레임워크) - 2.환경설정
  • [Network] 채팅 프로그램 만들기
  • 게임 언패킹과 리타게팅, 그리고 머티리얼에 대하여 ( 1 )
  • 에디터에서 FVector 수정을 위한 UPROPERTY 사용
DevJoo1120
DevJoo1120
  • DevJoo1120
    Jin's Programming
    DevJoo1120
  • 전체
    오늘
    어제
    • 분류 전체보기 (142)
      • 포트폴리오 (7)
        • Castlevania: Aria of Sorrow.. (7)
        • [UE5] KILL Everything (0)
      • C++ (0)
      • 라이브러리 (1)
      • 다이렉트X11 (0)
      • Unreal Engine (11)
        • Unreal Document (1)
        • 이것 저것 (8)
        • UI (1)
      • 자료구조 및 알고리즘 (0)
      • 책 정리 (3)
        • 코딩 테스트 합격자 되기 C++ 편 (10)
      • 코딩 테스트 (32)
        • 프로그래머스 (32)
      • 스파르타 코딩 언리얼 1기 (9)
        • 특강 (0)
        • C++와 Unreal Engine으로 3D .. (2)
      • TIL(Today I Learned) (63)
      • 영어 공부 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    WINAPI
    Til
    스파르타 코딩 클럽
    코딩 테스트 합격자 되기 c++ 편
    배열
    코딩 테스트
    정렬
    반복문
    팀 프로젝트
    Unreal Engine 5
    문자열
    프로그래머스
    Study
    C++
    코딩테스트
    책 정리
    과제
    map
    정리
    이중 반복문
  • hELLO· Designed By정상우.v4.10.5
DevJoo1120
[엔진 소스 코드 분석] 1 - LaunchWindows.cpp
상단으로

티스토리툴바