Partilhar via


Erro das ferramentas de linkagem LNK2019

símbolo externo não resolvido 'símbolo' referenciado na função 'função'

Observações

O código compilado para a função faz uma referência ou chamada para símbolo, mas o vinculador não pode encontrar a definição de símbolo em nenhuma das bibliotecas ou arquivos de objeto.

Esta mensagem de erro é seguida por erro fatal LNK1120. Para corrigir erros LNK1120, você deve corrigir todos os erros LNK2001 e LNK2019 primeiro.

Causas possíveis

Há muitas maneiras de obter este erro. Todos eles envolvem uma referência a uma função ou variável que o vinculador não conseguiu resolver, ou encontrar uma definição para. O compilador pode identificar quando um símbolo não é declarado, mas não pode dizer quando o símbolo não está definido. É porque a definição pode estar em um arquivo de origem ou biblioteca diferente. Se um símbolo é referido, mas nunca definido, o vinculador gera um erro de símbolo externo não resolvido.

Aqui estão alguns problemas comuns que causam LNK2019:

O arquivo de origem que contém a definição do símbolo não é compilado

No Visual Studio, certifique-se de que o arquivo de origem que define o símbolo é compilado como parte do seu projeto. Verifique o diretório de saída de compilação intermediário para um ficheiro .obj correspondente. Se o arquivo de origem não for compilado, clique com o botão direito do mouse no arquivo no Gerenciador de Soluções e escolha Propriedades para verificar as propriedades do arquivo. A páginaGeral das > de Configuração deve mostrar um Tipo de Item do Compilador C/C++. Na linha de comando, verifique se o arquivo de origem que contém a definição está compilado.

O arquivo de objeto ou biblioteca que contém a definição do símbolo não está vinculado

No Visual Studio, verifique se o arquivo de objeto ou biblioteca que contém a definição de símbolo está vinculado como parte do seu projeto. Na linha de comando, verifique se a lista de arquivos a serem vinculados inclui o arquivo de objeto ou a biblioteca.

A declaração do símbolo não está escrita da mesma forma que a definição do símbolo

Verifique se você usa a ortografia e a maiúscula corretas na declaração e na definição, e onde quer que o símbolo seja usado ou chamado.

Uma função é usada, mas o tipo ou número dos parâmetros não corresponde à definição da função

A declaração de função deve corresponder à definição. Verifique se a chamada de função corresponde à declaração e se a declaração corresponde à definição. O código que invoca modelos de função também deve ter declarações de modelo de função correspondentes que incluam os mesmos parâmetros de modelo que a definição. Para obter um exemplo de uma incompatibilidade de declaração de modelo, consulte LNK2019e.cpp de exemplo na seção Exemplos.

Uma função ou variável é declarada, mas não definida

LNK2019 pode ocorrer quando existe uma declaração em um arquivo de cabeçalho, mas nenhuma definição correspondente é implementada. Para funções de membro ou static membros de dados, a implementação deve incluir o seletor de escopo de classe. Para obter um exemplo, consulte Corpo ou variável de função ausente.

A convenção de chamada é diferente entre a declaração de função e a definição de função

Algumas convenções de chamada (__cdecl, __stdcall, __fastcall, e __vectorcall) são codificadas como parte do nome decorado. Certifique-se de que a convenção de chamada é a mesma.

Um símbolo é definido em um arquivo C, mas declarado sem usar extern "C" em um arquivo C++

Um arquivo compilado como C cria nomes decorados para símbolos que são diferentes dos nomes decorados para os mesmos símbolos declarados em um arquivo C++, a menos que você use um extern "C" modificador. Certifique-se de que a declaração corresponde à ligação de compilação para cada símbolo. Da mesma forma, se você definir um símbolo em um arquivo C++ que será usado por um programa C, use extern "C" na definição.

Um símbolo é definido como static e, posteriormente, referenciado fora do arquivo

Em C++, ao contrário de C, as constantes globais têm static ligação. Para contornar essa limitação, você pode incluir as const inicializações em um arquivo de cabeçalho e incluir esse cabeçalho em seus arquivos .cpp, ou pode tornar a variável não constante e usar uma referência constante para acessá-la.

Um static membro de uma classe não está definido

Um static membro de classe deve ter uma definição exclusiva ou violará a regra de uma definição. Um static membro de classe que não pode ser definido em linha deve ser definido em um arquivo de origem usando seu nome totalmente qualificado. Se não estiver definido, o vinculador gerará LNK2019.

Uma dependência de compilação é definida apenas como uma dependência de projeto na solução

Em versões anteriores do Visual Studio, esse nível de dependência era suficiente. No entanto, a partir do Visual Studio 2010, o Visual Studio requer uma referência de projeto para projeto. Se o seu projeto não tiver uma referência de projeto para projeto, poderá receber este erro do linker. Adicione uma referência de projeto para projeto para corrigi-lo.

Um ponto de entrada não está definido

O código do aplicativo deve definir um ponto de entrada apropriado: main ou wmain para aplicativos de console e WinMain ou wWinMain para aplicativos do Windows. Para obter mais informações, consulte main argumentos de função e linha de comando ou WinMain função. Para usar um ponto de entrada personalizado, especifique a /ENTRY opção de vinculador (Entry-Point Symbol ).

Você cria um aplicativo de console usando configurações para um aplicativo do Windows

Se a mensagem de erro for semelhante ao símbolo WinMain externo não resolvido referenciado na funçãofunction_name, vincule 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).

Bibliotecas e arquivos de objeto vinculados ao seu código devem ser compilados para a mesma arquitetura do seu código. Certifique-se de que as bibliotecas às quais o projeto faz referência estão compiladas para a mesma arquitetura do projeto. Certifique-se de que a propriedade /LIBPATH ou Diretórios de Biblioteca Adicionais aponte para bibliotecas preparadas para a arquitetura correta.

Você usa diferentes opções do compilador para o inlining de funções em diferentes arquivos de origem

O uso de funções inline definidas em arquivos .cpp e a mistura de opções de compilador para funções inline em diferentes arquivos de origem pode causar LNK2019. Para obter mais informações, consulte Problemas de inserção de funções.

Você usa variáveis automáticas fora de seu escopo

As variáveis automáticas (âmbito da função) só podem ser utilizadas no âmbito dessa função. Essas variáveis não podem ser declaradas extern e usadas em outros arquivos de origem. Para obter um exemplo, consulte Variáveis automáticas (escopo da função).

Você chama funções intrínsecas ou passa tipos de argumento para funções intrínsecas que não são suportadas na sua arquitetura alvo.

Por exemplo, se você usar uma AVX2 opção intrínseca, mas não especificar a /ARCH:AVX2 opção do compilador, o compilador assumirá que o intrínseco é uma função externa. Em vez de gerar uma instrução embutida, o compilador gera uma chamada para um símbolo externo com o mesmo nome do intrínseco. Quando o vinculador tenta encontrar a definição dessa função ausente, ele gera LNK2019. Certifique-se de usar apenas intrínsecos e tipos suportados pela arquitetura de destino.

Você mistura código que usa o recurso nativo wchar_t com código que não o usa

O trabalho de conformidade da linguagem C++ realizado no Visual Studio 2005 tornou wchar_t um tipo nativo por padrão. Se nem todos os arquivos tiverem sido compilados usando as mesmas /Zc:wchar_t configurações, as referências de tipo podem não ser resolvidas para tipos compatíveis. Certifique-se de que os tipos wchar_t em todos os ficheiros de biblioteca e objeto são compatíveis. Atualize a partir de um wchar_t typedef ou utilize definições consistentes /Zc:wchar_t ao compilar.

Uma static biblioteca que foi criada usando uma versão do Visual Studio antes do Visual Studio 2015 pode causar erros de LNK2019 quando vinculada ao UCRT. Os ficheiros de cabeçalho da UCRT, <stdio.h>, <conio.h> e <wchar.h>, agora definem muitas variações de printf e scanf como funções de inline. As funções embutidas são implementadas por um conjunto menor de funções comuns. As exportações individuais para as funções embutidas não estão disponíveis nas bibliotecas UCRT padrão, que exportam apenas as funções comuns. Há algumas maneiras de resolver esse problema. O método que recomendamos é reconstruir a biblioteca herdada com sua versão atual do Visual Studio. Verifique se o código da biblioteca usa os cabeçalhos padrão para as definições das printf funções e scanf que causaram os erros. Outra opção para uma biblioteca herdada que você não pode reconstruir é adicionar legacy_stdio_definitions.lib à lista de bibliotecas vinculadas. Este ficheiro de biblioteca fornece símbolos para as funções printf e scanf que estão em linha nos cabeçalhos UCRT. Para obter mais informações, consulte a seção Bibliotecas em Visão geral de possíveis problemas de atualização.

Problemas com bibliotecas de terceiros e vcpkg

Se você vir esse erro quando estiver tentando configurar uma biblioteca de terceiros como parte de sua compilação, considere usar vcpkg. vcpkg é um gerenciador de pacotes C++ que usa suas ferramentas existentes do Visual Studio para instalar e compilar a biblioteca. VCPKG suporta uma lista grande e crescente de bibliotecas de terceiros. Ele define todas as propriedades de configuração e dependências necessárias para compilações bem-sucedidas como parte do seu projeto.

Ferramentas de diagnóstico

Às vezes, é difícil dizer por que o vinculador não consegue encontrar uma definição de símbolo específica. Muitas vezes, o problema é que você não incluiu o código que contém a definição em sua compilação. Ou, as opções de construção criaram diferentes nomes decorados para símbolos externos. Existem várias ferramentas e opções que podem ajudá-lo a diagnosticar LNK2019 erros.

  • A /VERBOSE opção de vinculador pode ajudá-lo a determinar quais arquivos o vinculador faz referência. Essa opção pode ajudá-lo a verificar se o arquivo que contém a definição do símbolo está incluído em sua compilação.

  • As opções /EXPORTS e /SYMBOLS do utilitário DUMPBIN podem ajudá-lo a descobrir quais símbolos são definidos em seu .dll e arquivos de biblioteca ou objetos. Verifique se os nomes decorados exportados correspondem aos nomes decorados que o vinculador procura.

  • O UNDNAME utilitário pode mostrar-lhe o símbolo externo não decorado equivalente para um nome decorado.

Exemplos

Aqui estão vários exemplos de código que causa erros de LNK2019, juntamente com informações sobre como corrigir os erros.

Um símbolo é declarado, mas não definido

Neste exemplo, uma variável externa é declarada, mas não definida:

// LNK2019.cpp
// Compile by using: cl /EHsc /W4 LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B isn't available to the linker
int main() {
   B[0] = ' ';   // LNK2019
}

Aqui está outro exemplo em que uma variável e uma função são declaradas como extern , mas nenhuma definição é fornecida:

// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

A menos que i e g sejam definidos em um dos arquivos incluídos 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 .obj arquivos ou .lib arquivos que contenham as definições para o vinculador.

Um static membro de dados é declarado, mas não definido

O LNK2019 também pode ocorrer quando um membro de dados static é 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;
}

Os parâmetros da declaração não correspondem à definição

O código que invoca modelos de função deve ter declarações de modelo de função correspondentes. As declarações devem incluir os mesmos parâmetros de modelo que 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 doesn't 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 inconsistentes wchar_t

Este exemplo 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 próximo exemplo usa a DLL no exemplo anterior e gera LNK2019 porque os tipos unsigned short* e WCHAR* não são os mesmos.

// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);

int main() {
   func(0);
}

Para corrigir esse erro, altere unsigned short para wchar_t ou WCHARou compile LNK2019g.cpp usando /Zc:wchar_t-.

Ver também

Para obter mais informações sobre possíveis causas e soluções para erros de LNK2019, LNK2001 e LNK1120, consulte a pergunta no Stack Overflow: What is an undefined reference/unresolved external symbol error and how do I fix it?.