Símbolo externo não resolvido nos arquivos de objetos

180

Durante a codificação no Visual Studio, recebi um erro de símbolo externo não resolvido e não tenho idéia do que fazer. Eu não sei o que está errado. Você poderia me decifrar? Onde devo procurar que tipo de erros?

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
Novellizator
fonte
26
Um símbolo não resolvido é aquele que você declarou em algum lugar, mas nunca definiu. Geralmente, isso significa que você #incluiu o arquivo de cabeçalho de uma biblioteca de terceiros, mas não informou ao vinculador onde encontrar os arquivos .obj correspondentes para a biblioteca.
deong
7
Erro bastante comum é que você definir uma função como um autônomo e esquecer o seletor de classe em sua .cpp arquivo: Você pode fazer isso (errado): void myFunc() { /* do stuff */ } Em vez de presente (direita): void A::myFunc() { /* do stuff */ }
jave.web
Você também pode adicionar suportes diretamente em seu cabeçalho arquivo se você não quer para defini-lo mais em seu arquivo .cpp, assim: void myFunc() {};.
Patapoom

Respostas:

303

Esse erro geralmente significa que alguma função tem uma declaração, mas não uma definição.

Exemplo:

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

// A.cpp

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

No seu caso, a definição não pode ser encontrada. O problema pode ser que você esteja incluindo um arquivo de cabeçalho, que traz algumas declarações de função, mas você:

  1. não defina as funções no seu arquivo cpp (se você mesmo escreveu esse código)
  2. não inclua o arquivo lib / dll que contém as definições

Um erro comum é que você define uma função como autônoma e esquece o seletor de classe, por exemplo A::, no seu arquivo .cpp :

Errado: void myFunc() { /* do stuff */ }
Certo: void A::myFunc() { /* do stuff */ }

Chris Morris
fonte
2
Como incluir o referido arquivo lib no meu projeto?
ATM
@tMJ Depende do ambiente que você está usando. Pesquisei tutoriais on-line ou neste site.
31814 Chris Morris
@ChrisMorris A definição da função não estava disponível, não porque eu não o vinculei corretamente ou algo assim. Mas, porque a dll não estava na memória e precisou ser carregada por meio de uma chamada LoadLibrary. (FTR)
tmj
2
O último conselho foi exatamente o problema aqui. Eu estava fazendo em void myFunc() {}vez de A::void myFunc() {}.
Charles
Resposta brilhante. Na verdade, eu havia esquecido tanto a parte (1) quanto a parte A :: depois de copiar o método de outro lugar.
RoG
24

Verifique se você está incluindo todos os arquivos de origem em sua solução que você está referenciando.

Se você não estiver incluindo o arquivo de origem (e, portanto, a implementação) da classe Fieldem seu projeto, ele não será construído e você não poderá vincular durante a compilação.

Como alternativa, talvez você esteja usando uma biblioteca estática ou dinâmica e esqueceu de informar o vinculador sobre os .libs?

Konrad
fonte
3
A indicação dos arquivos lib corretos resolveu o problema. Use Projeto-> Propriedades-> Vinculador-> Geral-> Diretórios Adicionais da Biblioteca e Projeto-> Propriedades-> Vinculador-> Entrada-> Dependências Adicionais para consultar o diretório lib e os arquivos lib
zak
11

Parece estar faltando uma biblioteca ou incluir, você pode tentar descobrir qual classe da sua biblioteca tem getName, getType etc ... e colocá-la no arquivo de cabeçalho ou usando #include.

Além disso, se eles pertencerem a uma biblioteca externa, não deixe de fazer referência a eles no arquivo do projeto. Por exemplo, se essa classe pertencer a um abc.lib, no seu Visual Studio

  1. Clique em Propriedades do projeto.
  2. Vá para Propriedades de configuração, C / C ++, Gerar, verifique se você aponta para o local abc.lib em Diretórios de inclusão adicionais. Em Vinculador, Entrada, verifique se você possui o abc.lib em Dependências adicionais.
Fylix
fonte
9

Acabei de ver o problema. Não consigo chamar uma função do main no arquivo .cpp, declarada corretamente no arquivo .h e definida no arquivo .c. Foi encontrado um erro no vinculador. Enquanto isso, eu posso chamar a função do arquivo .c usual. Possivelmente, depende da convenção de chamada. A solução foi adicionar as seguintes linhas preproc em todos os arquivos .h:

#ifdef __cplusplus
extern "C"
{
#endif

e estes no final

#ifdef __cplusplus
}
#endif
Alexey257
fonte
7

Ocorreu um erro em que meu projeto foi compilado como projeto x64 . e eu usei uma biblioteca que foi compilada como x86 .

Eu recompilei a biblioteca como x64 e ela a resolveu.

Gal Bracha
fonte
5

Às vezes, se um novo arquivo de cabeçalho for adicionado e esse erro começar, devido a isso, você precisará adicionar a biblioteca também para se livrar unresolved external symbol.

por exemplo:

#include WtsApi32.h

vai precisar:

#pragma comment(lib, "Wtsapi32.lib") 
Shashank
fonte
4

Eu tinha os mesmos erros de link, mas a partir de um projeto de teste que estava fazendo referência a outra dll. Descobriu que após adicionar _declspec(dllexport)na frente de cada função especificada na mensagem de erro, o link estava funcionando bem.

meJustAndrew
fonte
3

Acredito que a maioria dos pontos sobre as causas e soluções foi abordada por todos os colaboradores neste tópico. Eu só quero ressaltar o meu problema 'externo não resolvido', que foi causado por um tipo de dados definido como macro que é substituído de forma diferente do esperado, o que resulta no fornecimento desse tipo incorreto à função em questão e desde a função com o tipo nunca é definido, não poderia ter sido resolvido. Em particular, em C / C ++ -> Language, existe um atributo chamado 'Treat WChar_t As Built In Type, que deveria ter sido definido como' No (/ Zc: wchar_t-) ', mas não foi o meu caso.

Patrick Nguyen
fonte
graças, isso faz com que a questão do meu setup ( 'Não (/ Zc: wchar_t-)')
Noypi Gilas
2

Além da excelente resposta de Chris Morris acima, achei uma maneira muito interessante de receber essa mesma falha se você estiver chamando para um método virtual que não foi definido como puro, mas não possui sua própria implementação. É exatamente o mesmo motivo (o compilador não consegue encontrar uma implementação do método e, portanto, trapaceiros), mas meu IDE não detectou essa falha nem um pouco.

por exemplo, o código a seguir obteria um erro de compilação com a mesma mensagem de erro:

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

No entanto, alterar IamInterface myFunc () para ser um método virtual puro (um método que "deve" ser implementado, que, em vez de um método virtual que é um método que o "pode" ser substituído), eliminará o erro de compilação.

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

Espero que isso ajude a próxima pessoa StackOverFlow a percorrer o código!

GMLewisII
fonte
2

Consulte o Linker Tools Error LNK2019 no MSDN, que possui uma lista detalhada de problemas comuns que causam o LNK2019.

Alessandro Jacopson
fonte
2

Certifique-se de decorar seus arquivos de cabeçalho com

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

Coisas ruins - incluindo isso - podem acontecer se você não

Panouden
fonte
8
Que tal usar #pragma once?
Allen Linatoc 30/07/2015
2

Outro problema possível (sobre o qual acabei de coçar a cabeça por algum tempo):

Se você definir suas funções como inline, elas - é claro! - deverão ser definidas no cabeçalho (ou em um arquivo embutido ), não em um cpp .
No meu caso, eles estavam em um arquivo embutido, mas apenas porque eram uma implementação específica da plataforma, e um cpp incluiu esse arquivo inl correspondente ... em vez de um cabeçalho. Sim, isso acontece.

Também pensei em deixar isso aqui, talvez alguém encontre o mesmo problema e o encontre aqui.

Johann Studanski
fonte
1
Para quem desvalorizou isso: deixe pelo menos um comentário por que você acha que a resposta está errada ou não é útil. Um voto negativo sem um comentário é inútil, na melhor das hipóteses.
Johann Studanski
1

Eu apenas tive um tempo difícil com isso. Tudo foi logicamente configurado. Eu declarei um construtor, mas não o defini

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

Eu quase bati minha cabeça no teclado quando esqueci algo tão elementar.

Joe Plante
fonte
1

Estou fazendo C ++ pela primeira vez em muito tempo e recebo esse erro quando esqueço de adicionar o prefixo ClassName :: para a definição da função, pois isso é um pouco exclusivo do C ++. Então lembre-se de verificar isso também!

Matthew Hayes
fonte
1

Uma causa possível desse erro do vinculador também pode ser inlinefunções declaradas, mas não definidas em um arquivo de cabeçalho que é incluído em outro lugar. As funções embutidas devem ser definidas em todas as unidades de tradução em que são usadas.

bweber
fonte
0

PONTEIROS

Eu tive esse problema e resolvi-o usando o ponteiro. Vejo que esse não foi o seu problema, mas pensei em mencioná-lo, porque com certeza gostaria que estivesse aqui quando vi isso uma hora atrás. Meu problema era declarar uma variável de membro estática sem defini-la (a definição precisava vir após algumas outras configurações) e, é claro, um ponteiro não precisa de uma definição. Erro igualmente elementar: P

Rabel
fonte
3
Um exemplo seria altamente útil aqui.
precisa saber é o seguinte
0

Meu problema era um script não tinha o cpparquivo definido nele. Isso pode ser muito confuso, porque o Visual Studio possui o cpparquivo no projeto, mas algo completamente diferente está sendo construído.

ubershmekel
fonte
0

Meu problema foi: eu tive que fazer uma declaração de encaminhamento da classe cujo ctor era "externo não resolvido".

No arquivo em que recebi o erro, tive que colocar algo assim:

#include "ClassB" 

class ClassB; // this solved the problem

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

Obviamente, meu projeto é muito mais complicado e este é apenas um exemplo de trecho. Além disso, ao usar espaços para nome, declare-os também .

vicrucann
fonte
0

Passei algumas horas para descobrir que o problema era que meu arquivo principal tinha extensão em .cvez de.cpp

:/

Madhur
fonte
0

Ainda outra possibilidade de verificar, era o meu problema neste momento.

Eu adicionei a função à biblioteca e incluí a pasta de saída da biblioteca no caminho de pesquisa.

Mas eu também tinha uma pasta com uma versão mais antiga da biblioteca listada anteriormente, então o VS estava usando a biblioteca antiga e, é claro, não encontrando a nova função.

Francesco Dondi
fonte
0

Verifique se você não está tentando sobrecarregar os operadores de inserção ou extração como funções embutidas. Eu tive esse problema e ele só desapareceu quando removi a palavra-chave.

Beck
fonte
0

O que causou isso no meu caso:

Eu tinha um arquivo enorme Foo.cppsem um Foo.h. Foo.cppcomeçou assim:

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

Eu removi a palavra-chave "estática" e adicionei uma Foo.hcom isso:

extern int var;

Você vê o erro?

Perdi totalmente que o var foi originalmente definido em um espaço para nome, porque a declaração do espaço para nome estava oculta em outro código. A correção é alterar o externo assim:

namespace NS {
     extern int var;
}
Stefan Monov
fonte
0

Um possível motivo para o erro "Símbolo externo não resolvido" pode ser a convenção de chamada de função.

Verifique se todos os arquivos de origem estão usando o mesmo padrão (.c ou .cpp) ou especifique a convenção de chamada.

Caso contrário, se um arquivo for um arquivo C (source.c) e outro for um arquivo .cpp, e eles estiverem vinculados ao mesmo cabeçalho, será gerado o erro "símbolo externo não resolvido", porque a função é definida primeiro como uma função C cdecl, mas o arquivo C ++ usando o mesmo cabeçalho procurará uma função C ++.

Para evitar o "erro de símbolo externo não resolvido", verifique se a convenção de chamada da função é mantida a mesma entre os arquivos que a utilizam.

Flavio
fonte
0

Eu vim aqui procurando uma explicação possível antes de examinar mais de perto as linhas que precedem o erro do vinculador. Acabou sendo um executável adicional para o qual faltava a declaração global!

Jerry Miller
fonte
0

Acabei de ter o mesmo erro e consigo evitá-lo substituindo ;por {}no arquivo de cabeçalho.

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

Quando era void xyzMethod();, não queria compilar.

Lisedra
fonte