2012-03-29 12 views
140

Durante la codifica in Visual Studio ho ricevuto un errore di simbolo esterno non risolto e non ho idea di cosa fare. Non so cosa c'è che non va. Potresti per favore decifrarmi? Dove dovrei cercare il tipo di errori?Simbolo esterno non risolto nei file oggetto

1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" ([email protected]@@[email protected]@@Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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> > &)" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" ([email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@Z) 
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" ([email protected]@@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)" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@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)" ([email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@XZ) 
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" ([email protected]@@UAEXXZ) 
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals 
+23

Un simbolo non risolto è quello che hai dichiarato da qualche parte ma mai definito. Di solito, significa che hai incluso il file di intestazione di una libreria di terze parti ma non hai detto al linker dove trovare i file .obj corrispondenti per la libreria. – deong

+7

Un errore piuttosto comune è che si definisce una funzione come indipendente e si dimentica il selettore di classe nel file * .cpp *: ** Si esegue questa operazione (errata): ** 'void myFunc() {/ * do stuff * /} ' ** Invece di questo (a destra): **' void A :: myFunc() {/ * do stuff * /} ' –

+0

Puoi anche aggiungere parentesi direttamente nel tuo file ** header ** se non lo fai voglio definirlo di più nel tuo file .cpp, in questo modo: 'void myFunc() {};'. – Patapoom

risposta

259

Questo errore indica spesso che alcune funzioni hanno una dichiarazione, ma non una definizione.

Esempio:

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

// A.cpp 

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

Nel tuo caso, la definizione non può essere trovato. Il problema potrebbe essere che si sta includendo un file di intestazione, che porta in alcune dichiarazioni di funzione, ma si sia:

  1. non definiscono le funzioni nel file cpp (se hai scritto questo codice da soli)
  2. non includere il file lib/dll che contiene le definizioni

Un errore comune è che si definisce una funzione come indipendente e si dimentica il selettore di classe, ad es. A::, nella vostra cpp di file:

Sbagliato:void myFunc() { /* do stuff */ }
destra:void A::myFunc() { /* do stuff */ }

+0

Come includere il suddetto file lib nel mio progetto? – tMJ

+0

@ tMJ Dipende dall'ambiente in uso. Guarderei online tutorial, o su questo sito. –

+0

@ChrisMorris La definizione della funzione non era disponibile non perché non l'ho collegata correttamente o qualcosa del genere. Ma, poiché la DLL non era in memoria e doveva essere caricata tramite una chiamata LoadLibrary. (FTR) – tMJ

17

Verificare di includere tutti i file di origine all'interno della soluzione a cui si fa riferimento.

Se non si include il file di origine (e quindi l'implementazione) per la classe Field nel progetto, non verrà creato e non sarà possibile effettuare il collegamento durante la compilazione.

In alternativa, forse si sta utilizzando una libreria statica o dinamica e si è dimenticato di comunicare al linker i .lib s?

+0

Il riferimento ai file lib corretti ha risolto il problema. Usa Progetto-> Proprietà-> Linker-> Generale-> Directory libreria aggiuntiva e Progetto-> Proprietà-> Linker-> Input-> Dipendenze aggiuntive per fare riferimento alla directory lib e ai file lib – zak

11

Sembra mancare una libreria o include, puoi provare a capire quale classe della tua libreria hanno getName, getType ecc ... e inserirla nel file di intestazione o usando #include.

Anche se questi provengono da una libreria esterna, assicurarsi di fare riferimento ad essi sul file di progetto. Ad esempio, se questa classe appartiene a un abc.lib, in Visual Studio

  1. Fare clic su Proprietà progetto.
  2. Passare a Proprietà di configurazione, C/C++, Generare, verificare che si punti alla posizione abc.lib in Additional Includi directory. Sotto Linker, Inserisci, assicurati di avere l' abc.lib in Dipendenze aggiuntive.
+0

Questa soluzione ha funzionato per me in Visual Studio 2015. – DumbQuesionGuy314

1

Ho appena avuto un momento difficile con questo. Tutto è stato configurato logicamente.Ho dichiarato un costruttore, ma non ha definito che

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

ho quasi sbattuto la testa sulla mia tastiera quando ho dimenticato qualcosa di così elementare.

1

Sto facendo un po 'di C++ per la prima volta da molto tempo, e sto ricevendo questo errore quando ho dimenticato di aggiungere il prefisso ClassName :: per la definizione della funzione, poiché questo è un po' unico per C++. Quindi ricorda di controllare anche quello!

0

PUNTATORI

Ho avuto questo problema e risolto esso utilizzando il puntatore. Vedo che questo non era il tuo problema, ma ho pensato di parlarne perché spero davvero che sia stato qui quando l'ho visto un'ora fa. Il mio problema era di dichiarare una variabile membro statica senza definirla (la definizione doveva venire dopo alcune altre impostazioni) e ovviamente un puntatore non ha bisogno di una definizione. Ugualmente errore elementare: P

+2

Un esempio sarebbe molto utile qui. – moffeltje

2

In aggiunta all'eccellente risposta di Chris Morris sopra, ho trovato un modo molto interessante per ricevere lo stesso errore se si sta chiamando ad un metodo virtuale che non è stato impostato su puro ma non lo fa è la sua stessa implementazione. È lo stesso identico motivo (il compilatore non riesce a trovare un'implementazione del metodo e quindi dei truffatori), ma il mio IDE non ha colto questo difetto in minima parte.

per esempio, il codice seguente otterrebbe un errore di compilazione con lo stesso messaggio di errore:

//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; 
    } 
} 

Tuttavia, la modifica IamInterface myFunc() per essere un metodo virtuale puro (un metodo che "deve" essere implementato , che rispetto a un metodo virtuale che è un metodo che il "can" può essere sovrascritto) eliminerà l'errore di compilazione.

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

Si spera che questo aiuti il ​​prossimo StackOverFlow a passare il codice!

2

Assicurati di decorare i vostri file di intestazione con

#ifndef YOUR_HEADER_H 
#define YOUR_HEADER_H 

// your header code here 

#endif 

cose brutte -inclusi questo- può accadere se non

+6

Che ne dici di usare '' #pragma once''? –

6

Ho appena visto il problema che non posso chiamare una funzione dal file principale in .cpp, dichiarato correttamente nel file .h e definito nel file .c. Si è verificato un errore del linker. Nel frattempo posso chiamare la funzione dal solito file .c. Forse dipende dalla convenzione di chiamata. Soluzione era quella di aggiungere le seguenti linee preproc in ogni file h:

#ifdef __cplusplus 
extern "C" 
{ 
#endif 

e questi alla fine

#ifdef __cplusplus 
} 
#endif 
2

credo che la maggior parte dei punti che riguardano le cause ei rimedi sono stati coperti da tutti i contribuenti in questo thread. Voglio solo evidenziare il mio problema "irrisolto esterno", è stato causato da un tipo di dati definito come macro che viene sostituito in modo diverso dal previsto, il che si traduce in un tipo errato fornito alla funzione in questione, e poiché la funzione con tipo non è mai stato definito, non avrebbe potuto essere risolto. In particolare, in C/C++ -> Lingua, c'è un attributo chiamato "Treat WChar_t As Built in Type", che avrebbe dovuto essere definito come "No (/ Zc: wchar_t-)" ma non nel mio caso.

0

Il mio problema era uno sconscript non aveva il file cpp definito in esso. Questo può essere molto confuso perché Visual Studio ha il file cpp nel progetto, ma qualcos'altro sta costruendo interamente.

0

Il mio problema era: dovevo fare la dichiarazione in avanti della classe il cui autore era "esterno non risolto".

Nel file dove ho ottenuto l'errore, ho dovuto mettere qualcosa di simile:

#include "ClassB" 

class ClassB; // this solved the problem 

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

Naturalmente, il mio progetto è molto più complicato e questo è solo un frammento di esempio. Anche quando si utilizzano gli spazi dei nomi, declare them as well.

2

a volte se viene aggiunto un nuovo file di intestazione e questo errore inizia a causa di questo, è necessario aggiungere anche la libreria per eliminare unresolved external symbol.

ad esempio:

#include WtsApi32.h 

avrà bisogno di:

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

appena trascorso un paio di ore per scoprire che il problema era il mio file principale aveva estensione .c invece di .cpp

:/

2

Ho avuto gli stessi errori di collegamento, ma da un progetto di test che faceva riferimento a un'altra DLL. Ho scoperto che dopo aver aggiunto _declspec(dllexport) davanti a ciascuna funzione specificata nel messaggio di errore, il collegamento funzionava bene.

0

verifica che la piattaforma di destinazione del progetto VS sia coerente con i file binari che hai scaricato.

Ad esempio: Piattaforma: Win32 ---- VS2013 32bit 6.3 (statico)

1

Una possibile causa di questo errore linker possono anche essere inline funzioni dichiarate ma non definite in un'intestazione file che è quindi incluso da qualche altra parte. Le funzioni inline devono essere definite in ogni unità di traduzione in cui sono utilizzate.

4

Ho riscontrato un errore in cui il mio progetto è stato compilato come progetto x64. e ho utilizzato una libreria compilata come x86.

Ho ricompilato la libreria come x64 e l'ho risolta.

0

Un'altra possibilità di controllare, questa volta era il mio problema.

Avevo aggiunto la funzione alla libreria e incluso la cartella di output della libreria nel percorso di ricerca.

Ma avevo anche una cartella con una versione precedente della libreria elencata prima, quindi VS stava usando la vecchia libreria e, naturalmente, non trovava la nuova funzione.

-1

Ancora un altro possibile problema (che ho appena graffiato la mia testa per qualche tempo):!

Se si definiscono le funzioni inline, essi-naturalmente -hanno da definire nel intestazione (o un file in linea ), non un cpp.
Nel mio caso, si trovavano in un file inline, ma solo perché erano un'implementazione specifica della piattaforma e un cpp includeva il corrispondente inl file ... anziché un'intestazione. Sì, s ** t succede.

Ho pensato di lasciare questo anche qui, forse qualcun altro si imbatte nello stesso problema e lo trova qui.

0

Assicurarsi che non si stia tentando di sovraccaricare gli operatori di inserimento o estrazione come funzioni in linea. Ho avuto questo problema e è andato via solo quando ho rimosso quella parola chiave.

0

Cosa aveva causato nel mio caso:

ho avuto un file enorme Foo.cpp senza Foo.h. Foo.cpp ha iniziato in questo modo:

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

ho tolto la parola "statica" e ha aggiunto un Foo.h con questo:

extern int var; 

Non si vede l'errore?

Mi mancava totalmente che var fosse originariamente definito in un namespace, perché la dichiarazione dello spazio dei nomi era sepolta in altro codice. La correzione consiste nel cambiare l'extern in questo modo:

namespace NS { 
    extern int var; 
} 
Problemi correlati