링커 도구 오류 LNK2019

'function' 함수에서 참조된 extern해결되지 않은 al 기호 'symbol'입니다.

함수에 대해 컴파일된 코드는 기호참조하거나 호출하지만 링커는 라이브러리 또는 개체 파일에서 기호 정의를 찾을 수 없습니다.

이 오류 메시지 뒤에 치명적인 오류 LNK1120. 오류 LNK1120 해결하려면 먼저 모든 LNK2001 및 LNK2019 오류를 수정해야 합니다.

가능한 원인

이 오류를 가져오는 방법에는 여러 가지가 있습니다. 모두 링커가 확인할 수 없는 함수 또는 변수에 대한 참조를 포함하거나 정의를 찾습니다. 컴파일러는 기호가 선언되지 않은 시기를 식별할 수 있지만 기호가 정의되지 않은 시기를 알 수 없습니다. 정의가 다른 원본 파일 또는 라이브러리에 있을 수 있기 때문입니다. 기호를 참조하지만 정의되지 않은 경우 링커는 해결되지 extern않은 al 기호 오류를 생성합니다.

LNK2019를 일으키는 일반적인 문제는 다음과 같습니다.

기호의 정의가 포함된 원본 파일이 컴파일되지 않음

Visual Studio에서 기호를 정의하는 소스 파일이 프로젝트의 일부로 컴파일되는지 확인합니다. 일치하는 .obj 파일에 대한 중간 빌드 출력 디렉터리를 확인합니다. 원본 파일이 컴파일되지 않은 경우 솔루션 탐색기 파일을 마우스 오른쪽 단추로 클릭한 다음 속성을 선택하여 파일의 속성을 검사. 구성 속성>일반 페이지에는 C/C++ 컴파일러의 항목 형식 표시됩니다. 명령줄에서 정의가 포함된 원본 파일이 컴파일되었는지 확인합니다.

기호의 정의가 포함된 개체 파일 또는 라이브러리가 연결되지 않음

Visual Studio에서 기호 정의가 포함된 개체 파일 또는 라이브러리가 프로젝트의 일부로 연결되어 있는지 확인합니다. 명령줄에서 연결할 파일 목록에 개체 파일 또는 라이브러리가 포함되어 있는지 확인합니다.

기호 선언은 기호의 정의와 같은 철자가 아닙니다.

선언과 정의 모두에서 올바른 맞춤법 및 대문자 표시를 사용하고 기호가 사용되거나 호출되는 위치를 확인합니다.

함수가 사용되지만 매개 변수의 형식 또는 수가 함수 정의와 일치하지 않습니다.

함수 선언은 정의와 일치해야 합니다. 함수 호출이 선언과 일치하고 선언이 정의와 일치하는지 확인합니다. 함수 템플릿을 호출하는 코드에는 정의와 동일한 템플릿 매개 변수를 포함하는 일치하는 함수 템플릿 선언도 있어야 합니다. 템플릿 선언 불일치의 예는 예제 섹션의 샘플 LNK2019e.cpp를 참조하세요.

함수 또는 변수가 선언되었지만 정의되지 않았습니다.

헤더 파일에 선언이 있지만 일치하는 정의가 구현되지 않은 경우 LNK2019 발생할 수 있습니다. 멤버 함수 또는 static 데이터 멤버의 경우 구현에 클래스 범위 선택기가 포함되어야 합니다. 예제를 보려면 Missing Function Body or Variable를 참조하십시오.

호출 규칙은 함수 선언과 함수 정의 간에 다릅니다.

일부 호출 규칙(__cdecl, __stdcall, __fastcall__vectorcall)은 데코레이팅된 이름의 일부로 인코딩됩니다. 호출 규칙이 동일한지 확인합니다.

기호는 C 파일에 정의되어 있지만 C++ 파일에서 사용하지 extern "C" 않고 선언됩니다.

C로 컴파일된 파일은 한정자를 사용하지 않는 한 C++ 파일에 선언된 것과 동일한 기호에 대해 데코레이팅된 이름과 다른 기호에 대해 데코레이팅 extern "C" 된 이름을 만듭니다. 선언이 각 기호에 대한 컴파일 링크와 일치하는지 확인합니다. 마찬가지로, C 프로그램에서 사용할 기호를 C++ 파일에서 정의하는 경우 정의에 extern "C" 을 사용하세요.

기호는 파일 외부로 static 정의되고 나중에 참조됩니다.

C++에서는 C와 달리 글로벌 const개미 는 링크가 있습니다 static . 이 제한을 해결하려면 헤더 파일에 초기화를 포함하고 const 해당 헤더를 .cpp 파일에 포함하거나 변수를const ant가 아닌 것으로 만들고 ant 참조를 const사용하여 액세스할 수 있습니다.

static 클래스의 멤버가 정의되지 않음

클래스 멤버에는 static 고유한 정의가 있어야 합니다. 또는 하나의 정의 규칙을 위반합니다. static 인라인으로 정의할 수 없는 클래스 멤버는 정규화된 이름을 사용하여 하나의 소스 파일에 정의되어야 합니다. 정의되지 않은 경우 링커는 LNK2019 생성합니다.

빌드 종속성은 솔루션에서 프로젝트 종속성으로만 정의됩니다.

이전 버전의 Visual Studio에서는 이 종속성 수준으로 충분했습니다. 그러나 Visual Studio 2010부터 Visual Studio에는 프로젝트-프로젝트 참조필요합니다. 프로젝트에 프로젝트-프로젝트 참조가 없는 경우 이 링커 오류가 표시될 수 있습니다. 프로젝트 간 참조를 추가하여 오류를 해결하세요.

진입점이 정의되지 않음

애플리케이션 코드는 적절한 진입점을 main 정의해야 합니다. 즉 wmain , 콘솔 애플리케이션 또는 WinMainwWinMain Windows 애플리케이션에 대해 정의해야 합니다. 자세한 내용은 함수 및 명령줄 인수 또는WinMain함수를 참조 main 하세요. 사용자 지정 진입점을 사용하려면 (진입점 기호) 링커 옵션을 지정 /ENTRY 합니다.

Windows 애플리케이션에 대한 설정을 사용하여 콘솔 애플리케이션을 빌드합니다.

오류 메시지가 함수function_name 참조되는 extern해결되지 않은 al 기호 WinMain 와 유사한 경우 대신 사용하여 /SUBSYSTEM:CONSOLE/SUBSYSTEM:WINDOWS연결합니다. 이 설정에 대한 자세한 내용과 Visual Studio에서 이 속성을 설정하는 방법에 대한 지침은 (하위 시스템 지정)을 참조 /SUBSYSTEM 하세요.

코드에 연결된 라이브러리 및 개체 파일은 코드와 동일한 아키텍처에 대해 컴파일되어야 합니다. 프로젝트 참조 라이브러리가 프로젝트와 동일한 아키텍처에 대해 컴파일되었는지 확인합니다. 또는 추가 라이브러리 디렉터리 속성이 올바른 아키텍처를 위해 빌드된 라이브러리를 가리키는지 확인 /LIBPATH 합니다.

다른 소스 파일에서 함수 인라인 처리에 다른 컴파일러 옵션을 사용합니다.

여러 소스 파일에서 .cpp 파일에 정의된 인라인된 함수를 사용하고 함수 인라이닝 컴파일러 옵션을 혼합하면 LNK2019가 발생할 수 있습니다. 자세한 내용은 Function Inlining Problems을 참조하세요.

해당 범위 외부의 자동 변수를 사용합니다.

자동(함수 범위) 변수는 해당 함수의 범위 내에서만 사용할 수 있습니다. 이러한 변수는 extern 으로 선언할 수 없으며 다른 소스 파일에서 사용할 수 없습니다. 예제를 보려면 Automatic (Function Scope) Variables를 참조하십시오.

내장 함수를 호출하거나 인수 형식을 대상 아키텍처에서 지원되지 않는 내장 함수에 전달합니다.

예를 들어 내장 함수를 AVX2 사용하지만 컴파일러 옵션을 지정 /ARCH:AVX2 하지 않으면 컴파일러는 내장 함수가 al 함수라고 extern가정합니다. 컴파일러는 인라인 명령을 생성하는 대신 내장 함수와 동일한 이름을 가진 al 기호에 대한 호출 extern을 생성합니다. 링커가 이 누락된 함수의 정의를 찾으려고 할 때 LNK2019가 생성됩니다. 대상 아키텍처에서 지원하는 내장 함수 및 형식만 사용해야 합니다.

네이티브 wchar_t 를 사용하는 코드와 그렇지 않은 코드를 혼합합니다.

Visual Studio 2005에서 수행된 C++ 언어 규칙 작업은 기본적으로 네이티브 형식을 만들었습니다 wchar_t . 모든 파일이 동일한 /Zc:wchar_t 설정을 사용하여 컴파일되지 않은 경우 형식 참조가 호환되는 형식으로 확인되지 않을 수 있습니다. 모든 라이브러리 및 개체 파일의 형식이 호환되는지 확인 wchar_t 합니다. typedef에서 wchar_t 업데이트하거나 컴파일할 때 일관된 /Zc:wchar_t 설정을 사용합니다.

static Visual Studio 2015 이전 버전의 Visual Studio를 사용하여 빌드된 라이브러리는 UCRT와 연결할 때 LNK2019 오류가 발생할 수 있습니다. UCRT 헤더 파일<stdio.h><conio.h><wchar.h>이제 여러 *printf* 변형을 *scanf* 함수로 inline 정의합니다. 인라인 함수는 더 작은 공통 함수 집합에 의해 구현됩니다. 인라인 함수에 대한 개별 내보내기 기능은 일반 함수만 내보내는 표준 UCRT 라이브러리에서 사용할 수 없습니다. 이 문제를 해결하는 방법에는 몇 가지가 있습니다. 권장되는 방법은 현재 버전의 Visual Studio를 사용하여 레거시 라이브러리를 다시 빌드하는 것입니다. 라이브러리 코드에서 오류를 발생시킨 함수 및 *scanf* 정의에 *printf* 표준 헤더를 사용하는지 확인합니다. 다시 빌드할 수 없는 레거시 라이브러리의 또 다른 옵션은 연결하는 라이브러리 목록에 추가하는 legacy_stdio_definitions.lib 것입니다. 이 라이브러리 파일은 UCRT 헤더에 *printf* 인라인된 함수 및 *scanf* 기호를 제공합니다. 자세한 내용은 잠재적인 업그레이드 문제 개요의 라이브러리 섹션을 참조하세요.

타사 라이브러리 문제 및 vcpkg

빌드의 일부로 타사 라이브러리를 구성하려고 할 때 이 오류가 표시되는 경우 vcpkg를 사용하는 것이 좋습니다. vcpkg 는 기존 Visual Studio 도구를 사용하여 라이브러리를 설치하고 빌드하는 C++ 패키지 관리자입니다. vcpkg 는 점점 커지는 타사 라이브러리 목록을 지원합니다. 프로젝트의 일부로 성공적인 빌드에 필요한 모든 구성 속성 및 종속성을 설정합니다.

진단 도구

링커가 특정 기호 정의를 찾을 수 없는 이유를 알 수 없는 경우가 있습니다. 종종 문제는 빌드에 정의가 포함된 코드를 포함하지 않았다는 것입니다. 또는 빌드 옵션이 al 기호에 대해 extern다른 데코레이팅된 이름을 만들었습니다. LNK2019 오류를 진단하는 데 도움이 되는 몇 가지 도구와 옵션이 있습니다.

  • /VERBOSE 링커 옵션은 링커가 참조하는 파일을 결정하는 데 도움이 될 수 있습니다. 이 옵션을 사용하면 기호 정의가 포함된 파일이 빌드에 포함되어 있는지 여부를 확인할 수 있습니다.

  • /EXPORTS 유틸리티 및 DUMPBIN 옵션은 .dll 및 /SYMBOLS 개체 또는 라이브러리 파일에 정의된 기호를 검색하는 데 도움이 될 수 있습니다. 내보낸 데코레이팅된 이름이 링커가 검색하는 데코레이팅된 이름과 일치하는지 확인합니다.

  • 이 유틸리티는 UNDNAME 데코레이팅된 이름에 해당하는 데코레이 extern트되지 않은 al 기호를 표시할 수 있습니다.

예제

다음은 오류를 해결하는 방법에 대한 정보와 함께 LNK2019 오류를 발생시키는 코드의 몇 가지 예입니다.

기호가 선언되었지만 정의되지 않았습니다.

이 예제에서 external 변수는 선언되지만 정의되지는 않습니다.

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

변수와 함수가 선언되지만 extern 정의가 제공되지 않는 또 다른 예는 다음과 같습니다.

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

빌드에 포함된 파일 중 하나에 정의되지 않는 한 ig 링커는 LNK2019 생성합니다. 컴파일의 일부로써 정의를 포함하는 소스 코드 파일을 포함하여 오류를 해결할 수 있습니다. 또는 정의가 포함된 파일이나 .lib 파일을 링커에 전달할 .obj 수 있습니다.

static 데이터 멤버가 선언되었지만 정의되지 않음

LNK2019 데이터 멤버가 static 선언되었지만 정의되지 않은 경우에도 발생할 수 있습니다. 다음 샘플에서는 LNK2019가 생성되며 해결 방법을 보여 줍니다.

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

선언 매개 변수가 정의와 일치하지 않음

함수 템플릿을 호출하는 코드에는 일치하는 함수 템플릿 선언이 있어야 합니다. 선언에는 정의와 동일한 템플릿 매개 변수가 포함되어야 합니다. 다음 샘플에서는 사용자 정의 연산자에 LNK2019가 생성되고 해결 방법을 보여 줍니다.

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

일관되지 않은 wchar_t 형식 정의

이 샘플에서는 내보내기를 사용하는 WCHARDLL을 만듭니다. 이 DLL은 다음으로 wchar_t확인됩니다.

// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}

다음 샘플에서는 이전 샘플에서 DLL을 사용하고 형식 unsigned short*WCHAR* 이 동일하지 않으므로 LNK2019 생성합니다.

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

int main() {
   func(0);
}

이 오류를 해결하려면 .를 사용하여 /Zc:wchar_t-LNK2019g.cpp를 변경 unsigned shortwchar_t 하거나 WCHAR컴파일합니다.

참고 항목

LNK2019, LNK2001 및 LNK1120 오류에 대한 가능한 원인 및 해결 방법에 대한 자세한 내용은 Stack Overflow 질문을 What is an undefined reference/unresolved external symbol error and how do I fix it?참조하세요.