`WinMain @ 16 ‘에 대한 정의되지 않은 참조 CDT하면 다음과 같은 결과가

를 사용하여 프로그램을 빌드하려고 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의 비표준을 호출 하는 기계 코드 실행이 시작되는 함수 인 런타임 라이브러리 진입 점을 사용합니다 .winMainCRTStartupWinMainmain

그러나 그것을 고치는 데 큰 문제는 없습니다.

당신이해야 할 일은 마이크로 소프트 링커에게 어떤 진입 점을 사용할 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 ++는 mainGUI 하위 시스템 프로그램에서도 표준에 문제가 없습니다 .

그렇다면 무엇이 문제일까요?

글쎄, 당신은 아마 없는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를 업데이트 한 것과 관련이 있는지 확실하지 않습니다. 인과 관계 일 수도 있고 단순히 상관 관계 일 수도 있습니다. 해당 요소에 대한 통찰력을 자유롭게 언급하십시오!)