`WinMain @ 16 'के लिए अपरिभाषित संदर्भ


110

जब मैं प्रोग्राम का उपयोग करके निर्माण करने की कोशिश करता Eclipse CDTहूं, तो मुझे निम्नलिखित मिलते हैं:

/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): `WinMain @ 16 को अपरिभाषित संदर्भ

ऐसा क्यों है? और, मैं इस मुद्दे को कैसे हल कर सकता हूं?

जवाबों:


184

निम्नलिखित Windows API- स्तरीय कार्यक्रम पर विचार करें:

#define NOMINMAX
#include <windows.h>

int main()
{
    MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}

अब इसे GNU टूलकिन (यानी g ++) का उपयोग करके बनाते हैं, कोई विशेष विकल्प नहीं। यहाँ gnucसिर्फ एक बैच फ़ाइल है जो मैं उसके लिए उपयोग करता हूं। यह केवल जी ++ को अधिक मानक बनाने के लिए विकल्पों की आपूर्ति करता है:

C: \ test> gnuc x.cpp

C: \ test> objdump -x a.exe | खोज / i "^ सबसिस्टम"
सबसिस्टम 00000003 (विंडोज CUI)

C: \ test> _

इसका मतलब है कि डिफ़ॉल्ट रूप से लिंकर ने एक कंसोल सबसिस्टम एक्ज़ीक्यूटेबल का उत्पादन किया । सबसिस्टम फ़ाइल शीर्षक में मूल्य विंडोज बताता है कि सेवाओं कार्यक्रम की आवश्यकता है। इस स्थिति में, कंसोल सिस्टम के साथ, प्रोग्राम को कंसोल विंडो की आवश्यकता होती है।

यह प्रोग्राम के पूरा होने के लिए कमांड दुभाषिया का इंतजार करने का कारण भी बनता है।

अब इसे GUI सबसिस्टम के साथ बनाते हैं , जिसका अर्थ है कि प्रोग्राम को कंसोल विंडो की आवश्यकता नहीं है:

C: \ test> gnuc x.cpp -mwindows

C: \ test> objdump -x a.exe | खोज / i "^ सबसिस्टम"
सबसिस्टम 00000002 (Windows GUI)

C: \ test> _

उम्मीद है कि यह अब तक ठीक है, हालांकि -mwindowsझंडा सिर्फ अर्ध-प्रलेखित है।

उस अर्ध-प्रलेखित झंडे के बिना बिल्डिंग को विशेष रूप से लिंकर को बताना होगा कि सबसिस्टम एक इच्छाओं को महत्व देता है, और कुछ विंडोज एपीआई आयात पुस्तकालयों को सामान्य रूप से स्पष्ट रूप से निर्दिष्ट करना होगा:

C: \ test> gnuc x.cpp -Wl, -subsystem, windows

C: \ test> objdump -x a.exe | खोज / i "^ सबसिस्टम"
सबसिस्टम 00000002 (Windows GUI)

C: \ test> _

यह ठीक काम किया, GNU टूलकिन के साथ।

लेकिन माइक्रोसॉफ्ट टूलकिन के बारे में क्या है, यानी विज़ुअल सी ++?

ठीक है, एक कंसोल सबसिस्टम निष्पादन योग्य के रूप में निर्माण ठीक काम करता है:

C: \ test> msvc x.cpp user32.lib
x.cpp

C: \ test> डंपबिन / हेडर x.exe | ढूँढें / मैं "सबसिस्टम" | ढूंढें / i "विंडोज"
               3 सबसिस्टम (विंडोज CUI)

C: \ test> _

हालाँकि, GUI सबसिस्टम के रूप में Microsoft के टूलकिन भवन डिफ़ॉल्ट रूप से काम नहीं करता है:

C: \ test> msvc x.cpp user32.lib / लिंक / सबसिस्टम: विंडोज़
x.cpp
LIBCMT.lib (wincrt0.obj): त्रुटि LNK2019: अनसुलझे बाहरी प्रतीक _WinMain @ 16 फ़ंक्शन में संदर्भित ___tmainCRTStartu
पी
x.exe: घातक त्रुटि LNK1120: 1 अनसुलझे बाहरी

C: \ test> _

तकनीकी रूप से ऐसा इसलिए है क्योंकि GUI सबसिस्टम के लिए Microsoft का लिंकर डिफ़ॉल्ट रूप से अमानक है । डिफ़ॉल्ट रूप से, जब सबसिस्टम GUI होता है, तो Microsoft का लिंकर रनटाइम लाइब्रेरी एंट्री पॉइंट का उपयोग करता है , वह फ़ंक्शन जहां मशीन कोड निष्पादन शुरू होता है, कहा जाता है winMainCRTStartup, जो मानक के WinMainबजाय Microsoft के गैर-मानक कॉल करता है main

हालांकि, इसे ठीक करने के लिए कोई बड़ी बात नहीं है।

आपको बस इतना करना है कि माइक्रोसॉफ्ट के लिंकर को यह बताना है कि कौन सा एंट्री पॉइंट इस्तेमाल करना है mainCRTStartup, जो मानक कहता है main:

C: \ test> msvc x.cpp user32.lib / लिंक / सबसिस्टम: विंडोज़ / प्रविष्टि: mainCRTStartup
x.cpp

C: \ test> डंपबिन / हेडर x.exe | ढूँढें / मैं "सबसिस्टम" | ढूंढें / i "विंडोज"
               2 सबसिस्टम (Windows GUI)

C: \ test> _

कोई समस्या नहीं, लेकिन बहुत थकाऊ। और इतना रहस्यमय और छिपा हुआ कि ज्यादातर विंडोज प्रोग्रामर, जो ज्यादातर केवल माइक्रोसॉफ्ट के गैर-मानक-बाय-डिफॉल्ट टूल का उपयोग करते हैं, उन्हें इसके बारे में भी नहीं पता है, और गलती से लगता है कि विंडोज जीयूआई सबसिस्टम प्रोग्राम "मानक" के WinMainबजाय गैर- मानक है main। पास होने में, C ++ 0x के साथ Microsoft को इससे समस्या होगी, क्योंकि कंपाइलर को तब विज्ञापन देना होगा कि क्या यह फ्री-स्टैंड या होस्टेड है (होस्ट किए जाने पर इसे मानक का समर्थन करना चाहिए main)।

वैसे भी, यही कारण है कि जी ++ गुम होने की शिकायत कर सकताWinMain है: यह एक मूर्खतापूर्ण गैर-मानक स्टार्टअप फ़ंक्शन है जो जीयूआई सबसिस्टम कार्यक्रमों के लिए माइक्रोसॉफ्ट के टूल को डिफ़ॉल्ट रूप से आवश्यक है।

लेकिन जैसा कि आप ऊपर देख सकते हैं, mainजीयूआई को जीयूआई सबसिस्टम कार्यक्रम के लिए मानक के साथ भी कोई समस्या नहीं है ।

तो समस्या क्या हो सकती है?

खैर, आप शायद याद कर रहे हैं एक 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। ): अपरिभाषित संदर्भ
`` WinMain @ 16 के लिए CE
एकत्रित 2: ld ने 1 निकास स्थिति लौटा दी

C: \ test> _

3
@ शेल्फ पी। स्टाइनबैक। आपके अच्छे उत्तर के लिए बहुत बहुत धन्यवाद। के लिए के रूप में All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main। क्या ऐसा करने का कोई तरीका है Eclipse CDTजैसा कि मैं कमांड लाइन का उपयोग नहीं कर रहा हूं। साभार
सादगी

1
@ user588855: चूंकि आप g ++ का उपयोग कर रहे हैं, इसलिए (शायद) आप पर लागू नहीं होता है। केवल अंत में हिस्सा (शायद) लागू होता है। यही है, एक mainया एक परिभाषित करें WinMain, या, सुनिश्चित करें कि संबंधित फ़ाइल परियोजना में शामिल है। चीयर्स,
चीयर्स और हीथ। -

@ शेल्फ पी। स्टाइनबैक। परिभाषित करने से आपका क्या मतलब है mainया winmain? साभार
सादगी

1
मैंने अभी main.cpp नामक एक फाइल बनाई थी जिसमें कोड था: int main () {}
वास्तव में

3
मुझे अच्छा होगा यदि प्रत्येक डाउनवोटर डाउनवोट को समझा सके। संभवतः अन्य पाठकों के लिए एक ही गलत धारणा है (जो भी है), और फिर हम इसे स्पष्ट कर सकते हैं। कुछ को गुमराह होने के बजाय सभी को फायदा होगा। तो, कृपया अपने पतन की व्याख्या करें। धन्यवाद।
चीयर्स एंड हीथ। - अल्फ

68

चीयर्स और हेट द्वारा उपरोक्त पोस्ट को संक्षेप में प्रस्तुत करना। - अल्फ, सुनिश्चित करें कि आपने main()या WinMain()परिभाषित किया है और जी ++ को सही काम करना चाहिए।

मेरी समस्या यह थी कि main()दुर्घटना से नाम स्थान के अंदर परिभाषित किया गया था।


बस इस सब के बारे में कुछ महत्वपूर्ण एहसास हुआ। मेरे मामले में, यह मुख्य नहीं मिल रहा था () क्योंकि मैंने कोई तर्क (argc, argv) घोषित नहीं किया था। एक बार जोड़ा गया, यह मुख्य पाया गया। इसके अलावा, यह कैसे काम करता है की प्रकृति का अर्थ है कि मिंगव अपने स्वयं के मुख्य को प्रदान करके मदद करने की कोशिश कर रहा है जो बदले में WinMain कहता है। GUI कार्यक्रमों में केवल WinMain होगा और मुख्य स्टब का उपयोग वहां पहुंचने के लिए किया जाता है। यदि आपके पास एक मुख्य है, तो वह इसके बजाय इसका उपयोग करता है।
जेफ मुइर

extern "C" int main (शून्य) ने मेरे लिए समस्या तय की
ड्रायलर

33

एसडीएल के साथ अपने आवेदन को संकलित करते समय मैं इस त्रुटि का सामना कर रहा था। यह SDL को परिभाषित करने के कारण था, यह SDL_main.h का अपना मुख्य कार्य है। SDL को रोकने के लिए मुख्य फ़ंक्शन को SDL_MAIN_HANDLED मैक्रो को SDL.h हैडर को शामिल करने से पहले परिभाषित करना होगा।


बहुत बढ़िया जवाब! +1
मोहम्मद कानन

आपका बहुत बहुत धन्यवाद! यह कमांड काम करता है: gcc main.c -I "E: \ Libs \ SDL2-devel-2.0.12-mingw \ SDL2-2.0.12 \ i686-w64-mingw32 \" -I "E: \ Libs \ SDL2_ttf- शामिल करें devel-2.0.15-mingw \ SDL2_ttf-2.0.15 \ i686-w64-mingw32 \ "-L" E: \ Libs \ SDL2-devel-2.0.12-mww \ SDL2-2.0.12 \ i686-w64 शामिल हैं mingw32 \ lib "एल" ई: \ Libs \ SDL2_ttf-devel-2.0.15-MinGW \ SDL2_ttf-2.0.15 \ i686-W64-mingw32 \ lib "-lSDL2 -lSDL2main -lSDL2_ttf -ओ app.exe
8Observer8

5

निर्माण से पहले अपनी .c फ़ाइल को सहेजने का प्रयास करें। मेरा मानना ​​है कि आपका कंप्यूटर एक फ़ाइल के लिए एक पथ संदर्भित कर रहा है जिसके अंदर कोई जानकारी नहीं है।

- C प्रोजेक्ट बनाते समय इसी तरह का मुद्दा


इसने वास्तव में मेरे मुद्दे को हल कर दिया है, और मैं इस टिप्पणी को छोड़ने में मदद कर रहा हूं ताकि इसे अधिक ध्यान दिया जा सके।
डेविड चेन

0

जांचें कि आपकी परियोजना में सभी फाइलें शामिल हैं:

जब मैंने cLion को अपडेट किया था, तब मुझे यही त्रुटि दिखाई दी थी। घंटों की छेड़छाड़ के बाद, मैंने देखा कि मेरी एक फाइल परियोजना के लक्ष्य में शामिल नहीं थी। जब मैंने इसे सक्रिय परियोजना में वापस जोड़ा, तब मुझे winmain16 के अपरिभाषित संदर्भ मिलना बंद हो गए, और कोड संकलित किया गया।

संपादित करें: अपने IDE के भीतर बिल्ड सेटिंग्स की जाँच करना भी सार्थक है।

(यह सुनिश्चित नहीं है कि यह त्रुटि हाल ही में आईडीई अपडेट होने से संबंधित है - कारण या सहसंबंधी हो सकती है। उस कारक पर किसी भी जानकारी के साथ टिप्पणी करने के लिए स्वतंत्र महसूस करें!)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.