본문 바로가기

기타

[C++] 짜증나는 링크애러!! 이렇게 해결했다.(LNK2001: unresolved external symbol )

LNK2001: unresolved external symbol "public: void __thiscall bag::insert(unsigned int const &)" (?insert@bag@@QAEXABI@Z)

이 애러..
대책없다
소스를 아무리 뒤져봐도 답이 나오지 않는다;

하지만 이 애러가 생기는 규칙적인 상황이 있었으니,
바로 클래스를 헤더파일(.h)과 cpp파일로 나누어서 담았을 때이다.
소스 어디에도 문제가 없어 보였다.

한시간 동안 고민하던 끝에
헤더파일에 소스의 모든 내용을 담아버렸다.
그리고 .cpp파일을 없애버렸다.
구조상 헤더파일과 cpp파일로 나누는 것이 맞지만,
이유를 알 수 없는 링크 애러를 한방에 날려 버릴 수 있는 좋은 해결책이다.
하지만 다른 애러가 발생할 수도 있다는거..

아래는 MSDN에 나온 애러의 원인들이다.

코딩 문제

  • LNK2001 진단 텍스트에서 __check_commonlanguageruntime_version이 확인되지 않은 외부 기호라고 보고할 경우 이를 해결하는 방법에 대한 자세한 내용은 LNK2019를 참조하십시오.
  • 멤버 템플릿 정의가 클래스 외부에 있습니다. Visual C++에서는 멤버 템플릿을 포함 클래스 내부에 완전히 정의해야 합니다. LNK2001 및 멤버 템플릿에 대한 자세한 내용은 기술 자료 문서 Q239436을 참조하십시오.
  • 코드 또는 모듈 정의(.def) 파일에서 대/소문자가 일치하지 않으면 LNK2001이 발생할 수 있습니다. 예를 들어, 한 C++ 소스 파일에 var1 변수를 명명한 다음 다른 파일에서 이 변수를 VAR1으로 액세스하려는 경우입니다.
  • 함수 인라이닝을 사용하는 프로젝트가 헤더 파일 대신에 .cpp 파일에 함수를 정의하면 LNK2001이 발생할 수 있습니다.
  • extern "C"를 사용하지 않고 C++ 프로그램에서 C 함수를 호출하면 컴파일러가 C 명명 규칙을 사용하게 되므로 LNK2001이 발생할 수 있습니다. 컴파일러 옵션 /Tp/Tc를 사용하면 컴파일러가 파일 이름 확장명에 관계 없이 파일을 C 또는 C++로 컴파일합니다. 이러한 옵션으로 인해 함수 이름이 예상했던 이름과 달라질 수 있습니다.
  • 외부 링크를 사용하지 않는 데이터 또는 함수를 참조하려고 하면 LNK2001이 발생할 수 있습니다. C++에서 extern으로 명시적으로 지정되지 않은 인라인 함수 및 const 데이터는 내부 링크를 사용합니다.
  • 함수 본문 또는 변수 누락으로 인해 LNK2001이 발생할 수 있습니다. 함수 프로토타입이나 extern 선언을 사용하면 컴파일러가 오류 발생 없이 작업을 계속할 수 있지만, 예약된 변수 공간이나 함수 코드가 없으므로 링커가 변수의 참조나 주소에 대한 호출을 확인할 수 없습니다.
  • 함수 선언에 있는 매개 변수 형식과 일치하지 않는 매개 변수 형식을 사용하는 함수를 호출하면 LNK2001이 발생할 수 있습니다. 이름 데코레이션은 함수의 매개 변수를 최종으로 데코레이트된 함수 이름에 포함시킵니다.
  • 잘못 포함된 프로토타입으로 인해, 컴파일러가 제공되지 않는 함수 본문을 기대하는 경우에는 LNK2001이 발생할 수 있습니다. F 함수에 대한 클래스 구현과 비클래스 구현을 모두 사용하는 경우에는 C++ 범위 결정 규칙에 유의하십시오.
  • C++를 사용할 때 클래스 정의에 함수 프로토타입을 포함시키고 해당 클래스에 대한 함수의 구현을 포함시키지 못하면 LNK2001이 발생할 수 있습니다.
  • 추상 기본 클래스의 생성자나 소멸자에서 순수 가상 함수를 호출하려고 하면 LNK2001이 발생할 수 있습니다. 순수 가상 함수에서는 기본 클래스가 구현되지 않습니다.
  • 정적 변수가 선언된 파일 외부에서 정적 변수에 액세스하려고 하면 LNK2001이 발생할 수 있습니다. 정의에 따라 static 한정자를 사용하여 선언된 함수는 파일 범위를 사용합니다. 정적 변수는 동일한 제한 사항을 갖습니다.
  • 함수 범위에 속하지 않는 함수(지역 변수) 내에 선언된 변수를 사용하려고 하면 LNK2001이 발생할 수 있습니다.
  • 여러 파일에서 C++의 전역 상수를 사용하려고 하면 LNK2001이 발생할 수 있습니다. C에서와는 달리, C++에서는 전역 상수정적 링크를 사용합니다. 이 제한 사항을 고려하려면 헤더 파일에 const 초기화를 포함시킨 다음 해당 헤더를 .cpp 파일에 포함시키거나, 변수를 비상수로 만든 다음 상수 참조를 사용하여 액세스하면 됩니다.
  • ATL 프로젝트의 릴리스 버전을 빌드할 경우에는 CRT 시작 코드가 필요한지 여부를 표시해야 합니다. 이를 해결하려면 다음 중 하나를 수행하십시오.
    • 전처리기 목록에서 _ATL_MIN_CRT를 제거하면 CRT 시작 코드를 포함할 수 있도록 정의됩니다. 자세한 내용은 일반 구성 설정 속성 페이지를 참조하십시오.
    • 가능하다면 CRT 시작 코드를 필요로 하는 CRT 함수에 대한 호출을 제거하고 대신에 Win32 동등 항목을 사용하십시오. 예를 들어, strcmp 대신에 lstrcmp를 사용하십시오. CRT 시작 코드를 필요로 한다고 알려진 함수에는 몇몇 문자열 함수와 부동 소수점 함수가 있습니다.




나의 경우
함수 인라이닝을 사용하는 프로젝트가 헤더 파일 대신에 .cpp 파일에 함수를 정의하면 LNK2001이 발생할 수 있습니다.
에 해당되었다.
헤더파일에서 인라이닝을 하는데 CPP에서도 함수를 정의했기 때문인 것 같다.

가장 좋은 공부 방법은
msdl 검색이다.
위 애러 관련 검색은 아래 링크를 확인하기 바란다.
http://search.msdn.microsoft.com/search/Default.aspx?query=LNK2001&brand=msdn&locale=ko-kr&refinement=00&lang=ko-kr