Erro das Ferramentas de Vinculador LNK2019
símbolo externo não resolvido 'symbol' referenciada na função 'function'
O vinculador não foi possível localizar uma definição para o símbolo externo "symbol"usada na função"function". Há muitos problemas que podem causar esse erro. Este tópico o ajudará a identificar a causa e encontrar uma solução.
Um símbolo externo é o nome declarado que você usar no código-fonte para se referir a algo que é definido em outro módulo — por exemplo, uma função externa ou uma variável global. O vinculador é responsável por resolver todas as referências de símbolo externo em cada módulo quando eles estão vinculados em um aplicativo ou DLL. Se o vinculador não conseguir encontrar uma definição de correspondência para um símbolo externo em qualquer um dos arquivos vinculados, ele gera LNK2019. Esse erro pode ocorrer se o arquivo de código ou na biblioteca de origem que tem a definição do símbolo não estiver incluído na compilação. Ele também pode ocorrer se o nome que o vinculador procura não corresponde ao nome do símbolo no módulo em que o define.
O código que usa a vinculação C++ usa Decoração do nome, também conhecido como -desconfiguração do nome, para codificar informações adicionais sobre o tipo do símbolo e convenção junto com o nome de símbolo de chamada. O nome decorado é o nome que o vinculador procura para resolver símbolos externos. Como ele se torna parte do nome decorado do símbolo, se o tipo de declaração da referência de símbolo não coincide com o tipo de declaração de definição de símbolo, erro LNK2019 pode resultar. A mensagem de erro mostra o símbolo externo e seu nome decorado para ajudá-lo a encontrar a causa do erro.
Problemas comuns
Aqui estão alguns problemas comuns que causam LNK2019:
a declaração do símbolo não foi digitada o mesmo que a definição do símbolo. Verifique se que a ortografia correta foi usada.
Uma função é usada, mas o tipo ou o número de parâmetros não coincidem com a definição de função. A declaração de função deve corresponder a definição. Código que chama as funções de modelo também deve ter as declarações de função de modelo que incluem os mesmos parâmetros de modelo que a definição de correspondência. Verifique se a chamada de função corresponde a declaração e a declaração corresponde à definição.
Uma função ou variável é declarada mas não definido. Para obter um exemplo, consulte Corpo de função ou variável ausente.
a convenção de chamada é diferente entre a declaração da função e a definição de função. Convenções de chamada (cdecl, stdcall, fastcall, ou vectorcall) são codificados como parte do nome decorado. Verifique se a convenção de chamada é o mesmo.
Um símbolo é definido em um arquivo de C, mas declarado sem usar extern "C" em um arquivo C++. Símbolos definidos em um arquivo que é compilado como C tem diferentes nomes decorados símbolos declarado em um arquivo de C++, a menos que você use um extern "C" modificador. Verifique se a declaração corresponde a vinculação de compilação para cada símbolo.
Da mesma forma, se você definir um símbolo em um arquivo de C++ que será usado por um programa em C, use extern "C" na definição.
Um símbolo é definido como estático e posteriormente referenciado fora do arquivo. Em C++, ao contrário de C, constantes globais ter static vinculação. Para contornar essa limitação, você pode incluir o const inicializações em um cabeçalho de arquivo e incluem esse cabeçalho nos arquivos. cpp, ou você pode fazer a variável não constante e usar uma referência de constante para acessá-lo.
Um membro estático de uma classe não está definido. Um membro de classe estática deve ter uma definição exclusiva ou violar a regra de definição de um. Um membro de classe estática que não pode ser definidas embutidas deve ser definido em um módulo usando seu nome totalmente qualificado. Se ele não for definido em todos os, gerado pelo vinculador LNK2019.
Uma dependência de compilação é definida somente como uma dependência de projeto na solução. Em versões anteriores do Visual Studio, esse nível de dependência foi suficiente. No entanto, começando com o Visual Studio 2010, Visual Studio requer um referência de projeto a projeto. Se seu projeto não tem uma referência de projeto para projeto, você poderá receber esse erro de vinculador. Adicione uma referência de projeto a projeto para corrigi-lo.
Criar um aplicativo de console usando configurações de um aplicativo do Windows. Se a mensagem de erro é unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup, link usando /SUBSYSTEM:CONSOLE em vez de /SUBSYSTEM:WINDOWS. Para obter mais informações sobre essa configuração e para obter instruções sobre como definir essa propriedade no Visual Studio, consulte /SUBSYSTEM (especificar subsistema).
Usar opções do compilador diferentes para a função inlining em diferentes módulos. Usando funções embutidas definidas em arquivos. cpp e combinação de opções do compilador inlining função em diferentes módulos pode causar LNK2019. Para obter mais informações, consulte Problemas de inlining da função.
Usar variáveis automáticas fora de seu escopo. Variáveis automáticas (escopo de função) podem ser usados somente no escopo de função. Essas variáveis não podem ser declaradas extern e usado em outros módulos. Para obter um exemplo, consulte Variáveis automáticas (escopo da função).
Chamar funções instrinsic ou passar tipos de argumento para as funções intrínsecas que não têm suporte em sua arquitetura de destino. Por exemplo, se você usar um AVX2 intrínseco, mas não especificar o avx2 opção de compilador, o compilador pressupõe que intrínseca é uma função externa. Em vez de gerar uma instrução embutido, o compilador gera uma chamada para um símbolo externo com o mesmo nome que intrínseca. Quando o vinculador tenta localizar a definição dessa função ausente, ele gera LNK2019. Verifique se você só usar intrínsecos e tipos compatíveis com sua arquitetura de destino.
Misturar código que usa wchar_t nativo com código não. Trabalho de conformidade de linguagem C++ que foi feito no Visual C++ 2005 fez wchar_t um tipo nativo por padrão. Você deve usar o /Zc:wchar_t- opção de compilador para gerar código compatível com módulos compilados usando versões anteriores do Visual C++. Se nem todos os módulos tiverem sido compilados usando o mesmo /Zc:wchar_t configurações, tipo referências podem não ser resolvidas em tipos compatíveis. Verifique wchar_t tipos em todos os módulos são compatíveis, atualizando os tipos que são usados ou usando consistente /Zc:wchar_t configurações quando você compilar.
Para obter mais informações sobre possíveis causas e soluções LNK2019, consulte a pergunta de estouro de pilha o que é um erro de símbolo externo indefinido referência/não resolvidos e como corrigi-lo?.
Ferramentas de diagnóstico
Pode ser difícil saber por que o vinculador não pode encontrar uma definição de símbolo específico. Geralmente, o problema é que você não incluiu o código em sua compilação ou criaram diferentes opções de compilação decorados nomes para símbolos externos. Há várias ferramentas e opções que podem ajudar a diagnosticarem um erro de LNK2019.
O /verbose opção de vinculador pode ajudá-lo a determinar quais arquivos as referências do vinculador. Isso pode ajudá-lo a verificar se o arquivo que contém a definição do símbolo foi incluído na sua compilação.
O /EXPORTA e /símbolos opções do utilitário DUMPBIN podem ajudá-lo a descobrir quais símbolos são definidos nos arquivos. dll e objeto ou biblioteca. Verifique se que o arquivo decorados nomes correspondem que a decorado nomeia o vinculador procura.
O utilitário UNDNAME pode mostrar o símbolo externo não decorado equivalente para um nome decorado.
Exemplos
Aqui estão alguns exemplos de código que causa um erro LNK2019, juntamente com informações sobre como corrigir o erro.
Um símbolo é declarado mas não definido
O exemplo a seguir gera LNK2019 porque um símbolo externo é declarado mas não definido:
// LNK2019.cpp
// Compile by using: cl /EHsc LNK2019.cpp
// LNK2019 expected
extern char B[100]; // B is not available to the linker
int main() {
B[0] = ' '; // LNK2019
}
Aqui está outro exemplo:
// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Se i e g não são definidos em um dos arquivos na compilação, o vinculador gera LNK2019. Você pode corrigir os erros, incluindo o arquivo de código fonte que contém as definições como parte da compilação. Como alternativa, você pode passar para o arquivos. obj de vinculador ou arquivos. lib que contêm as definições.
Um membro de dados estáticos é declarado mas não definido
LNK2019 também pode ocorrer quando um membro de dados estáticos é declarado mas não definido. O exemplo a seguir gera LNK2019 e mostra como corrigi-lo.
// LNK2019b.cpp
// Compile by using: cl /EHsc LNK2019b.cpp
// LNK2019 expected
struct C {
static int s;
};
// Uncomment the following line to fix the error.
// int C::s;
int main() {
C c;
C::s = 1;
}
Parâmetros de declaração não coincidem com definição
Código que chama as funções de modelo deve ter correspondência declarações de função do modelo. Declarações devem incluir os mesmos parâmetros de modelo a definição. O exemplo a seguir gera LNK2019 em um operador definido pelo usuário e mostra como corrigi-lo.
// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;
template<class T> class
Test {
// The operator<< declaration does not match the definition below:
friend ostream& operator<<(ostream&, Test&);
// To fix, replace the line above with the following:
// template<typename T> friend ostream& operator<<(ostream&, Test<T>&);
};
template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
return os;
}
int main() {
Test<int> t;
cout << "Test: " << t << endl; // LNK2019 unresolved external
}
Definições de tipo wchar_t inconsistente
O exemplo a seguir cria uma DLL que tem uma exportação que usa WCHAR, que resolve para wchar_t.
// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
O exemplo a seguir usa a DLL no exemplo anterior e gera LNK2019 porque os tipos unsigned short * e WCHAR * não são iguais.
// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
Para resolver esse erro, altere unsigned short para wchar_t ou WCHAR, ou compile LNK2019g.cpp usando /Zc:wchar_t-.