답변:
다음 Windows API 수준 프로그램을 고려하십시오.
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
이제 특별한 옵션없이 GNU 도구 모음 (예 : g ++)을 사용하여 빌드 해 보겠습니다. 여기 gnuc
에 제가 사용하는 배치 파일이 있습니다. g ++를 더 표준으로 만드는 옵션 만 제공합니다.
C : \ test> gnuc x.cpp C : \ test> objdump -x a.exe | findstr / i "^ 하위 시스템" 하위 시스템 00000003 (Windows CUI) C : \ 테스트> _
이는 링커가 기본적으로 콘솔 하위 시스템 실행 파일을 생성했음을 의미합니다 . 파일 헤더 의 하위 시스템 값은 프로그램에 필요한 서비스를 Windows에 알려줍니다. 이 경우 콘솔 시스템에서는 프로그램에 콘솔 창이 필요합니다.
이것은 또한 명령 인터프리터가 프로그램이 완료 될 때까지 기다리게합니다.
이제 GUI 하위 시스템으로 빌드 해 보겠습니다 . 이는 프로그램에 콘솔 창이 필요하지 않음을 의미합니다.
C : \ test> gnuc x.cpp -mwindows C : \ test> objdump -x a.exe | findstr / i "^ 하위 시스템" 하위 시스템 00000002 (Windows GUI) C : \ 테스트> _
-mwindows
플래그가 반 문서화 되었지만 지금까지는 괜찮습니다 .
반 문서화 된 플래그없이 빌드하려면 링커에게 원하는 하위 시스템 값을 더 구체적으로 알려야하며 일부 Windows API 가져 오기 라이브러리는 일반적으로 명시 적으로 지정해야합니다.
C : \ test> gnuc x.cpp -Wl, -subsystem, windows C : \ test> objdump -x a.exe | findstr / i "^ 하위 시스템" 하위 시스템 00000002 (Windows GUI) C : \ 테스트> _
GNU 툴체인에서는 잘 작동했습니다.
그러나 Microsoft 도구 체인, 즉 Visual C ++는 어떻습니까?
음, 콘솔 하위 시스템 실행 파일로 빌드하면 잘 작동합니다.
C : \ test> msvc x.cpp user32.lib x.cpp C : \ test> dumpbin / headers x.exe | / i "서브 시스템"찾기 | / i "Windows"찾기 3 하위 시스템 (Windows CUI) C : \ 테스트> _
그러나 Microsoft의 도구 모음을 GUI 하위 시스템으로 구축하면 기본적으로 작동하지 않습니다.
C : \ test> msvc x.cpp user32.lib / link / subsystem : windows x.cpp LIBCMT.lib (wincrt0.obj) : 오류 LNK2019 : ___tmainCRTStartu 함수에서 참조 된 해결되지 않은 외부 기호 _WinMain @ 16 피 x.exe : 치명적인 오류 LNK1120 : 해결되지 않은 외부 1 개 C : \ 테스트> _
기술적으로 이것은 Microsoft의 링커 가 GUI 하위 시스템에 대해 기본적으로 비표준 이기 때문 입니다. 기본적으로 하위 시스템이 GUI 인 경우 Microsoft의 링커는 표준 대신 Microsoft의 비표준을 호출 하는 기계 코드 실행이 시작되는 함수 인 런타임 라이브러리 진입 점을 사용합니다 .winMainCRTStartup
WinMain
main
그러나 그것을 고치는 데 큰 문제는 없습니다.
당신이해야 할 일은 마이크로 소프트 링커에게 어떤 진입 점을 사용할 mainCRTStartup
것인지 , 즉 표준을 호출 하는를 알려주 는 것입니다 main
.
C : \ test> msvc x.cpp user32.lib / link / subsystem : windows / entry : mainCRTStartup x.cpp C : \ test> dumpbin / headers x.exe | / i "서브 시스템"찾기 | / i "Windows"찾기 2 하위 시스템 (Windows GUI) C : \ 테스트> _
문제 없지만 매우 지루합니다. 그리고 대부분 Microsoft의 비표준 기본 도구 만 사용하는 대부분의 Windows 프로그래머는 이에 대해 알지 못하며 Windows GUI 하위 시스템 프로그램이 표준이 아닌 비표준 프로그램을 "반드시"가져야한다고 잘못 생각하고 WinMain
있습니다. main
. 지나가는 과정에서 C ++ 0x를 사용하면 컴파일러가 독립형인지 호스팅되는지 (호스팅 될 때 표준을 지원해야 함 main
) 광고해야하기 때문에이 문제가 발생합니다 .
어쨌든 이것이 g ++ 가WinMain
누락 에 대해 불평 할 수 있는 이유입니다 . 이것은 GUI 하위 시스템 프로그램에 대해 Microsoft 도구가 기본적으로 필요로하는 어리석은 비표준 시작 기능입니다.
그러나 위에서 볼 수 있듯이 g ++는 main
GUI 하위 시스템 프로그램에서도 표준에 문제가 없습니다 .
그렇다면 무엇이 문제일까요?
글쎄, 당신은 아마 없는 을 main
. 그리고 당신은 (적절한) WinMain
것도 없을 것입니다 ! 그런 다음 g ++는 main
(그렇지 않음) 및 Microsoft의 비표준 WinMain
( 그렇지 않음) 을 검색 한 후 후자가 누락되었다고보고합니다.
빈 소스로 테스트 :
C : \ test> 유형 nul> y.cpp C : \ test> gnuc y.cpp -mwindows c : / program files / mingw / bin /../ lib / gcc / mingw32 / 4.4.1 /../../../ libmingw32.a (main.o) : main.c :(. text + 0xd2 ) : 정의되지 않은 참조 ce-`WinMain @ 16 ' collect2 : ld가 1 종료 상태를 리턴했습니다. C : \ 테스트> _
main
하거나 WinMain
관련 파일이 프로젝트에 포함되어 있는지 확인하십시오. 건배,
main
또는 정의는 무엇을 의미 winmain
합니까? 감사합니다
Cheers와 hth의 위 게시물을 요약합니다. -Alf, 당신이 가지고 main()
있거나 WinMain()
정의 했는지 확인 하고 g ++가 올바른 일을해야합니다.
내 문제는 그것이 main()
실수로 네임 스페이스 내부에 정의 되었다는 것 입니다.
SDL로 애플리케이션을 컴파일하는 동안이 오류가 발생했습니다. 이것은 SDL_main.h에서 자체 주 함수를 정의하는 SDL로 인해 발생했습니다. SDL이 주 함수를 정의하는 것을 방지하려면 SDL.h 헤더가 포함되기 전에 SDL_MAIN_HANDLED 매크로를 정의해야합니다.
빌드하기 전에 .c 파일을 저장하십시오. 컴퓨터가 파일 내부에 정보가없는 파일 경로를 참조하고 있다고 생각합니다.
--C 프로젝트를 빌드 할 때 비슷한 문제가 발생했습니다.
프로젝트에 모든 파일이 포함되어 있는지 확인하십시오.
cLion을 업데이트 한 후에도 동일한 오류가 발생했습니다. 몇 시간의 작업 끝에 내 파일 중 하나가 프로젝트 대상에 포함되지 않았 음을 알았습니다. 활성 프로젝트에 다시 추가 한 후 winmain16에 대한 정의되지 않은 참조를 가져 오는 것을 중지하고 코드를 컴파일했습니다.
편집 : IDE 내에서 빌드 설정을 확인하는 것도 가치가 있습니다.
(이 오류가 최근에 IDE를 업데이트 한 것과 관련이 있는지 확실하지 않습니다. 인과 관계 일 수도 있고 단순히 상관 관계 일 수도 있습니다. 해당 요소에 대한 통찰력을 자유롭게 언급하십시오!)
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
.Eclipse CDT
명령 줄을 사용하지 않기 때문에 그렇게하는 방법이 있습니까? 감사합니다