를 사용하여 프로그램을 빌드하려고 Eclipse CDT
하면 다음과 같은 결과가 나타납니다.
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106) :`WinMain @ 16에 대한 정의되지 않은 참조
왜 그런 겁니까? 그리고이 문제를 어떻게 해결할 수 있습니까?
답변
다음 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 : \ 테스트> _
답변
Cheers와 hth의 위 게시물을 요약합니다. -Alf, 당신이 가지고 main()
있거나 WinMain()
정의 했는지 확인 하고 g ++가 올바른 일을해야합니다.
내 문제는 그것이 main()
실수로 네임 스페이스 내부에 정의 되었다는 것 입니다.
답변
SDL로 애플리케이션을 컴파일하는 동안이 오류가 발생했습니다. 이것은 SDL_main.h에서 자체 주 함수를 정의하는 SDL로 인해 발생했습니다. SDL이 주 함수를 정의하는 것을 방지하려면 SDL.h 헤더가 포함되기 전에 SDL_MAIN_HANDLED 매크로를 정의해야합니다.
답변
빌드하기 전에 .c 파일을 저장하십시오. 컴퓨터가 파일 내부에 정보가없는 파일 경로를 참조하고 있다고 생각합니다.
–C 프로젝트를 빌드 할 때 비슷한 문제가 발생했습니다.
답변
프로젝트에 모든 파일이 포함되어 있는지 확인하십시오.
cLion을 업데이트 한 후에도 동일한 오류가 발생했습니다. 몇 시간의 작업 끝에 내 파일 중 하나가 프로젝트 대상에 포함되지 않았 음을 알았습니다. 활성 프로젝트에 다시 추가 한 후 winmain16에 대한 정의되지 않은 참조를 가져 오는 것을 중지하고 코드를 컴파일했습니다.
편집 : IDE 내에서 빌드 설정을 확인하는 것도 가치가 있습니다.
(이 오류가 최근에 IDE를 업데이트 한 것과 관련이 있는지 확실하지 않습니다. 인과 관계 일 수도 있고 단순히 상관 관계 일 수도 있습니다. 해당 요소에 대한 통찰력을 자유롭게 언급하십시오!)