ऑब्जेक्ट फ़ाइलों में अनारक्षित बाहरी प्रतीक


180

विजुअल स्टूडियो में कोडिंग के दौरान मुझे एक बाहरी बाहरी प्रतीक त्रुटि मिली और मुझे पता नहीं है कि क्या करना है। मुझे नहीं पता कि क्या गलत हुआ। क्या आप मुझे समझा सकते हैं? मुझे किस तरह की त्रुटियों की तलाश करनी चाहिए?

1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField@Field@@QAEPAV1@PAV1@@Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Form@@QAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Field@@UAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField@@QAE@AAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt@Field@@UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe@Field@@UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals

26
एक अनसुलझा प्रतीक वह है जिसे आपने कहीं घोषित किया है लेकिन कभी परिभाषित नहीं किया है। आमतौर पर, इसका मतलब है कि आपने कुछ थर्ड पार्टी लाइब्रेरी की हेडर फ़ाइल को हटा दिया है, लेकिन लिंक करने वाले को यह नहीं बताया है कि लाइब्रेरी के लिए संबंधित .obj फाइल्स को कहाँ खोजें।
डोंग

7
बहुत आम गलती यह है कि आप एक फ़ंक्शन को स्टैंडअलोन के रूप में परिभाषित करते हैं और अपनी .cpp फ़ाइल में वर्ग चयनकर्ता को भूल जाते हैं : आप ऐसा करते हैं (गलत): void myFunc() { /* do stuff */ } इसके बजाय (दाएं): void A::myFunc() { /* do stuff */ }
jave.web

यदि आप इसे अपनी .cpp फ़ाइल में और अधिक परिभाषित नहीं करना चाहते हैं, तो आप अपनी हेडर फ़ाइल में सीधे ब्रैकेट जोड़ सकते हैं , जैसे void myFunc() {};:।
पैतापूम

जवाबों:


302

इस त्रुटि का अक्सर अर्थ होता है कि कुछ फ़ंक्शन में एक घोषणा है, लेकिन परिभाषा नहीं।

उदाहरण:

// A.hpp
class A
{
public:
  void myFunc(); // Function declaration
};

// A.cpp

// Function definition
void A::myFunc()
{
  // do stuff
}

आपके मामले में, परिभाषा नहीं मिल सकती है। मुद्दा यह हो सकता है कि आप एक हेडर फ़ाइल शामिल कर रहे हैं, जो कुछ फ़ंक्शन घोषणाओं में लाता है, लेकिन आप या तो:

  1. अपनी cpp फ़ाइल में कार्यों को परिभाषित न करें (यदि आपने यह कोड स्वयं लिखा है)
  2. लिब / dll फ़ाइल शामिल न करें जिसमें परिभाषाएँ हों

एक आम गलती है कि आप एक स्टैंडअलोन के रूप में एक समारोह को परिभाषित करने और वर्ग चयनकर्ता भूल जाते हैं, जैसे है A::अपने में, सीपीपी फ़ाइल:

गलत: void myFunc() { /* do stuff */ }
सही: void A::myFunc() { /* do stuff */ }


2
मेरी परियोजना में उक्त परिवाद फाइल को कैसे शामिल किया जाए?
tmj

@tMJ यह इस बात पर निर्भर करता है कि आप किस वातावरण का उपयोग कर रहे हैं। मैं ऑनलाइन या इस साइट पर ट्यूटोरियल देखूंगा।
क्रिस मॉरिस

@ChrisMorris फ़ंक्शन की परिभाषा उपलब्ध नहीं थी क्योंकि मैंने इसे ठीक से या कुछ लिंक नहीं किया था। लेकिन, क्योंकि dll मेमोरी में नहीं था और लोड लोडर कॉल के माध्यम से लोड किया जाना था। (FTR)
tmj

2
अंतिम सलाह यहाँ समस्या थी। मैं void myFunc() {}इसके बजाय कर रहा था A::void myFunc() {}
चार्ल्स

शानदार जवाब। मैं वास्तव में दोनों (1) और फिर ए :: भाग को कहीं और से विधि की नकल करने के बाद भूल गया था।
RoG

24

जाँच करें कि आप अपने समाधान के भीतर सभी स्रोत फ़ाइलों को शामिल कर रहे हैं जिन्हें आप संदर्भित कर रहे हैं।

यदि आप वर्ग के लिए स्रोत फ़ाइल (और इस प्रकार कार्यान्वयन) को शामिल नहीं कर रहे हैं Field अपनी परियोजना में इसे बनाया नहीं जाएगा और आप संकलन के दौरान लिंक करने में असमर्थ होंगे।

वैकल्पिक रूप से, शायद आप एक स्थिर या गतिशील पुस्तकालय का उपयोग कर रहे हैं और लिंकर को .libएस के बारे में बताना भूल गए हैं ?


3
सही lib फ़ाइलों को संदर्भित करने से समस्या हल हो गई। उपयोग परियोजना> गुण> Linker-> जनरल> अतिरिक्त लाइब्रेरी निर्देशिकाएँ और परियोजना> गुण> Linker-> इनपुट-> अतिरिक्त निर्भरता lib निर्देशिका और lib फ़ाइलें उल्लेख करने के लिए
ज़क

11

यह किसी लाइब्रेरी को याद कर रहा है या इसमें शामिल है, तो आप यह जानने की कोशिश कर सकते हैं कि आपकी लाइब्रेरी की कौन सी क्लास में गेटनेम, गेट टाइप इत्यादि हैं ... और हैडर फाइल या उपयोग में लाएं #include

इसके अलावा अगर ये बाहरी लाइब्रेरी से होते हैं, तो सुनिश्चित करें कि आप अपनी प्रोजेक्ट फ़ाइल पर इनका संदर्भ लें। उदाहरण के लिए, यदि यह वर्ग abc.lib से संबंधित है तो आपके विज़ुअल स्टूडियो में

  1. प्रोजेक्ट प्रॉपर्टीज पर क्लिक करें।
  2. कॉन्फ़िगरेशन गुण पर जाएं, C / C ++, उत्पन्न करें, सत्यापित करें कि आप अतिरिक्त शामिल निर्देशिकाओं के तहत abc.lib स्थान पर इंगित करते हैं। लिंकर, इनपुट के तहत, सुनिश्चित करें कि आपके पास अतिरिक्त निर्भरता के तहत abc.lib है।

9

मैंने सिर्फ उस समस्या को देखा है जिसे मैं मुख्य रूप से .cpp फ़ाइल से फ़ंक्शन नहीं कह सकता, सही ढंग से .h फ़ाइल में घोषित किया गया और inc फ़ाइल को परिभाषित किया गया। एक लिंकर त्रुटि का सामना करना पड़ा। इस बीच मैं सामान्य .c फ़ाइल से फ़ंक्शन को कॉल कर सकता हूं। संभवतः यह कॉल कन्वेंशन पर निर्भर करता है। समाधान हर .h फ़ाइल में निम्नलिखित प्रीप्रोक्ट लाइनें जोड़ने का था:

#ifdef __cplusplus
extern "C"
{
#endif

और अंत में ये

#ifdef __cplusplus
}
#endif

7

मेरे पास एक त्रुटि थी जहां मेरे प्रोजेक्ट को x64 प्रोजेक्ट के रूप में संकलित किया गया था । और मैंने एक पुस्तकालय का उपयोग किया है जिसे x86 के रूप में संकलित किया गया था ।

मैंने लाइब्रेरी को x64 के रूप में फिर से जोड़ दिया है और इसे हल कर दिया है।


5

कभी-कभी यदि कोई नई हेडर फ़ाइल जोड़ी जाती है, और यह त्रुटि उसी के कारण आने लगती है, तो आपको छुटकारा पाने के लिए लाइब्रेरी को भी जोड़ना होगा unresolved external symbol

उदाहरण के लिए:

#include WtsApi32.h

की आवश्यकता होगी:

#pragma comment(lib, "Wtsapi32.lib") 

4

मेरे पास समान लिंक त्रुटियां थीं, लेकिन एक परीक्षण परियोजना से जो एक और डीएल का उल्लेख कर रही थी। पता चला कि _declspec(dllexport)त्रुटि संदेश में निर्दिष्ट प्रत्येक फ़ंक्शन के सामने जोड़ने के बाद , लिंक अच्छी तरह से काम कर रहा था।


3

मेरा मानना ​​है कि इस थ्रेड में सभी योगदानकर्ताओं द्वारा कारणों और उपायों के बारे में अधिकांश बिंदुओं को शामिल किया गया है। मैं सिर्फ अपनी 'अनसुलझी बाहरी' समस्या के लिए इंगित करना चाहता हूं, यह मैक्रो के रूप में परिभाषित एक डेटाटाइप के कारण हुआ जो अपेक्षा से भिन्न रूप से प्रतिस्थापित हो जाता है, जिसके परिणामस्वरूप उस गलत प्रकार को फ़ंक्शन में आपूर्ति की जा रही है, और प्रकार के साथ फ़ंक्शन के बाद से कभी परिभाषित नहीं किया गया है, इसे हल नहीं किया जा सकता है। विशेष रूप से, C / C ++ -> भाषा के तहत, 'ट्रीक WChar_t As अंतर्निहित प्रकार' नामक एक विशेषता है, जिसे 'No (/ Zc: wchar_t-)' के रूप में परिभाषित किया जाना चाहिए था, लेकिन मेरे मामले में नहीं था।


धन्यवाद, यह मेरे सेटअप से समस्या का कारण बनता है ('नहीं (/ Zc: wchar_t-)')
Noypi Gilas

2

उपरोक्त क्रिस मॉरिस के उत्कृष्ट उत्तर के अलावा, मुझे एक बहुत ही दिलचस्प तरीका मिला जो आप उसी गलती को प्राप्त कर सकते हैं यदि आप एक आभासी तरीके से कॉल कर रहे हैं जो शुद्ध पर सेट नहीं किया गया है लेकिन इसका अपना कार्यान्वयन नहीं है। यह सटीक एक ही कारण है (संकलक विधि का कार्यान्वयन नहीं खोज सकता है और इसलिए बदमाश), लेकिन मेरी आईडीई ने कम से कम इस गलती को नहीं पकड़ा।

उदाहरण के लिए, निम्न कोड को एक ही त्रुटि संदेश के साथ संकलन त्रुटि मिलेगी:

//code testing an interface
class test
{
   void myFunc(); 
}

//define an interface
class IamInterface
{
    virtual void myFunc();
}

//implementation of the interface
class IamConcreteImpl
{
    void myFunc()
    {
       1+1=2;
    }
}

हालाँकि, IamInterface myFunc () को एक शुद्ध आभासी विधि (एक विधि जिसे "लागू" किया जाना चाहिए) को बदलने के लिए, एक आभासी विधि की तुलना में जो एक विधि है जिसे "ओवरराइड किया जा सकता है" संकलन त्रुटि को समाप्त कर देगा।

//define an interface
class IamInterface
{
    virtual void myFunc() = 0;
}

उम्मीद है कि यह अगले StackOverFlow व्यक्ति को कोड के माध्यम से कदम रखने में मदद करता है!



2

सुनिश्चित करें कि आप अपनी हेडर फ़ाइलों को सजाने के साथ

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

बुरी बातें - यदि आप नहीं करते हैं तो यह हो सकता है


8
कैसे उपयोग के बारे में #pragma once?
एलन लिनाटॉक

2

फिर भी एक और संभावित समस्या (कि मैंने कुछ समय के लिए अपने सिर को खरोंच दिया):

यदि आप अपने कार्यों को इस रूप में परिभाषित करते हैं inline, तो वे निश्चित रूप से - शीर्ष लेख (या इनलाइन फ़ाइल) में परिभाषित होने वाले हैं , न कि सीपीपी
मेरे मामले में, वे एक इनलाइन फ़ाइल में थे, लेकिन केवल क्योंकि वे एक मंच विशिष्ट कार्यान्वयन थे, और एक cpp इस इसी शामिल लीग फ़ाइल ... एक हैडर के बजाय। हाँ, s ** t होता है।

मैंने सोचा कि मैं इसे यहीं छोड़ दूंगा, हो सकता है कि कोई और उसी मुद्दे पर चले और उसे यहां पा ले।


1
जिसे यह कहा गया है: कम से कम एक टिप्पणी छोड़ो कि आपको क्यों लगता है कि उत्तर गलत है या सहायक नहीं है। एक टिप्पणी के बिना एक downvote सबसे अच्छा बेकार है।
जोहान स्टडांस्की 12

1

मेरे पास बस इसके साथ एक कठिन समय था। सब कुछ तार्किक रूप से स्थापित किया गया था। मैंने एक कंस्ट्रक्टर घोषित किया, लेकिन इसे परिभाषित नहीं किया

class SomeClass
{
   SomeClass();  // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}

मैंने अपने कीबोर्ड पर लगभग अपना सिर फोड़ लिया जब मैं कुछ प्राथमिक भूल गया।


1

मैं लंबे समय में पहली बार कुछ C ++ कर रहा हूं, और मुझे यह त्रुटि तब हो रही है जब मैं फ़ंक्शन परिभाषा के लिए ClassName :: उपसर्ग जोड़ना भूल जाता हूं, क्योंकि यह C ++ के लिए थोड़ा अनूठा है। तो उसके लिए भी जांच करना याद रखें!


1

इस लिंकर त्रुटि का एक संभावित कारण ऐसे inlineफ़ंक्शन भी हो सकते हैं जो घोषित किए जाते हैं लेकिन एक हेडर फ़ाइल में परिभाषित नहीं होते हैं जो तब कहीं और शामिल होते हैं। इनलाइन फ़ंक्शंस को हर अनुवाद इकाई में परिभाषित किया जाना है जिसका वे उपयोग कर रहे हैं।


0

संकेत

मुझे यह समस्या थी और पॉइंटर का उपयोग करके इसे हल किया। मैं देख रहा हूं कि यह आपका मुद्दा नहीं था, लेकिन मुझे लगा कि मैं इसका उल्लेख करूंगा क्योंकि मुझे यकीन है कि यह यहां था जब मैंने इसे एक घंटे पहले देखा था। मेरा मुद्दा इसे परिभाषित किए बिना एक स्थिर सदस्य चर घोषित करने के बारे में था (कुछ अन्य सेट अप के बाद आने वाली परिभाषा) और निश्चित रूप से एक सूचक को परिभाषा की आवश्यकता नहीं है। समान रूप से प्राथमिक गलती: पी


3
एक उदाहरण यहाँ अत्यधिक उपयोगी होगा।
moffeltje

0

मेरा मुद्दा एक स्कैन्सस्क्रिप्ट था जिसमें cppफ़ाइल को परिभाषित नहीं किया गया था। यह बहुत भ्रामक हो सकता है क्योंकि विज़ुअल स्टूडियो के पास cppप्रोजेक्ट में फ़ाइल है लेकिन पूरी तरह से कुछ और है।


0

मेरा मुद्दा यह था: मुझे उस वर्ग की घोषणा को आगे करना था जिसका ctor "अनसुलझे बाहरी" था।

फ़ाइल में जहाँ मुझे त्रुटि मिली, मुझे कुछ इस तरह से डालना था:

#include "ClassB" 

class ClassB; // this solved the problem

class ClassA{
    void foo(){
        ClassB* tmp = new ClassB();
        // ...
    }
};

बेशक, मेरी परियोजना बहुत अधिक जटिल है और यह सिर्फ एक स्निपेट उदाहरण है। नेमस्पेस का उपयोग करते समय, उन्हें भी घोषित करें


0

बस कुछ घंटों खर्च लगता है कि इस मुद्दे को अपने मुख्य फाइल एक्सटेंशन था .cबजाय.cpp

:/


0

फिर भी जांच करने की एक और संभावना, यह इस समय मेरी समस्या थी।

मैंने फ़ंक्शन को लाइब्रेरी में जोड़ा था, और लाइब्रेरी के आउटपुट फ़ोल्डर को खोज पथ में शामिल किया था।

लेकिन मेरे पास पहले से सूचीबद्ध पुस्तकालय के पुराने संस्करण के साथ एक फ़ोल्डर भी था, इसलिए वीएस पुराने पुस्तकालय का उपयोग कर रहा था, और निश्चित रूप से नया फ़ंक्शन नहीं मिल रहा था।


0

सुनिश्चित करें कि आप इनलाइन फ़ंक्शंस के रूप में सम्मिलन या निष्कर्षण ऑपरेटरों को अधिभारित करने की कोशिश नहीं कर रहे हैं। मुझे यह समस्या थी और यह केवल तभी चला गया जब मैंने उस कीवर्ड को हटा दिया।


0

मेरे मामले में इसका कारण क्या था:

मेरे पास Foo.cppFoo.h के बिना एक बहुत बड़ी फ़ाइल थी। Foo.cppइस तरह शुरू हुआ:

// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;

मैंने "स्थिर" कीवर्ड हटा दिया और इसके Foo.hसाथ जोड़ा :

extern int var;

क्या आप गलती देखते हैं?

मुझे पूरी तरह से याद है कि मूल रूप से नाम स्थान में परिभाषित किया गया था, क्योंकि नाम कोड की घोषणा अन्य कोड में दफन की गई थी। इस तरह से बाहरी परिवर्तन को ठीक करना है:

namespace NS {
     extern int var;
}

0

"अनारक्षित बाहरी प्रतीक" त्रुटि का एक संभावित कारण फ़ंक्शन कॉलिंग सम्मेलन हो सकता है।

सुनिश्चित करें कि सभी स्रोत फ़ाइलें समान मानक (.c या .cpp) का उपयोग कर रही हैं, या कॉलिंग कन्वेंशन निर्दिष्ट करें।

अन्यथा, यदि एक फ़ाइल एक सी फ़ाइल (source.c) है और दूसरी फ़ाइल एक .cpp फ़ाइल है, और वे एक ही हेडर से लिंक करते हैं, तो "अनसुलझे बाहरी प्रतीक" त्रुटि को फेंक दिया जाएगा, क्योंकि फ़ंक्शन पहले के रूप में परिभाषित किया गया है C cdecl फ़ंक्शन, लेकिन फिर उसी शीर्षलेख का उपयोग करके C ++ फ़ाइल C ++ फ़ंक्शन की खोज करेगा।

"अनारक्षित बाहरी प्रतीक त्रुटि" से बचने के लिए, सुनिश्चित करें कि फ़ंक्शन कॉलिंग कन्वेंशन का उपयोग फ़ाइलों के बीच समान रखा गया है।


0

मैं यहाँ लिंकर त्रुटि से पहले लाइनों पर एक करीब से नज़र रखने से पहले एक संभावित स्पष्टीकरण की तलाश में आया था। यह एक अतिरिक्त निष्पादन योग्य निकला, जिसके लिए वैश्विक घोषणा गायब थी!


0

मैं तो बस एक ही त्रुटि किया है और मैं की जगह से बचने के लिए प्रबंधन ;के साथ {}हेडर फाइल में।

#ifndef XYZ_h
#define XYZ_h
class XYZ
{
    public:
    void xyzMethod(){}
}
#endif

जब यह था void xyzMethod();यह संकलन नहीं करना चाहता था।

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