컴파일러가 알려주는 Error 중에서 가장 싫어하는 것이 무엇이냐고 묻는다면, 나는 서슴없이 LNK2019라고 대답할 것이다. 이것만큼 짜증나는 에러가 별로 없다.
보통 이 에러는 셋팅을 잘못해서 생기는 경우가 대부분이므로 발생할때마다 그 상황에 맞추어서 무엇이 문제인지를 찾아내야 한다. 프로그래밍 언어 문법 틀리는 것을 해결하는 것처럼 "일반적인 해결책"이 존재하지 않는다는 점이 이 에러가 싫은 가장 큰 이유이다. (정말 싫어 ㅠ_ㅜ)
결국 case by case 로 문제를 해결해야 하기 때문에 이제 생각날때마다 또는 LNK2019 에러를 맞을 때마다 이 포스트에 추가하겠다. 아래는 LNK2019 에러가 떳을 때 점검해보는 것이 좋은 셋팅들이다.
1. LIB 파일을 추가하지 않았는지 확인해보라!
필요한 LIB 파일을 프로젝트에 추가하지 않았을 경우에 LNK2019 Error가 발생한다.
"프로젝트 속성" (단축키 ALT + F7)을 열어서 아래 이미지에서처럼 '추가종속성'에 필요한 파일을 추가하도록 하자.
또는 코드에 직접 전처리기를 이용하여 아래처럼 추가해도 된다.
#pragma comment(lib, "dsound.lib")
2. 프로젝트에 헤더 파일(header file), 구현 파일 (implementation file)을 추가했는지 확인해보라!
이 경우는 소스코드에는 #include "SDKsound.h" 처럼 헤더 파일을 추가했지만, Visual Studio의 프로젝트에는 헤더파일과 구현파일 추가하지 않은 경우를 말한다. 바로 아래 이미지 같은 경우인데 이 경우에도 LNK2019 가 발생할 수 있다.
< SDKSound.h, SDKwavefile.h, SDKSound.cpp, SDKwavefile.cpp 가 추가되어 있지 않다. >
아래 이미지처럼 #include로 포함시킨 헤더파일과 구현파일 모두를 프로젝트에 추가해야지 LNK2019 Error가 발생하지 않는다.
< 프로젝트에 모두 추가 되어 있으므로 LNK2019 Error 발생 안 함 >
3. Release VS Debug mode - 빌드 모드(build mode)를 전환하지 않았나 생각해보라!
사용하는 IDE에 따라 다르겠지만, Visual Studio는 Release mode와 debug mode의 빌드 셋팅을 '각각' 해주어야 한다. 즉, debug mode에서 셋팅을 바꿨다고 release mode에서 똑같이 적용되는게 아니라는 말이다.
위 이미지처럼 build mode를 전환할 때는 셋팅 값 바꿔줘야 하는게 있는지 한 번쯤 생각해보시라!
4. c, cpp 처럼 다른 확장자를 갖고 있는 파일을 같은 프로젝트에 넣고 링크하지 말아라!
방금 같은 연구실에 있는 형이 LG전자 아르바이트를 해주다가 LNK2019 에러를 맞았다! 와우!
문제는 아주 간단했다. 하나의 프로젝트에 c와 cpp 파일을 모두 넣고 링크했던 것이다. 문법은 기본적으로 같으므로 컴파일에서는 문제가 없지만, c와 cpp는 Naming Mangling이 다르기 때문에 링킹 에러가 터진다. 간단한 메크로를 사용하면 이를 피해갈 수 있다. 정확한 내용은 아래의 글을 참조하길 바란다.
http://sadiles.blog.me/10099382864
아주 간단한 해결책도 존재한다! c확장자를 cpp로 바꿔라!
5. inline 함수의 선언과 정의를 헤더 파일과 구현 파일로 분리하지 말아라!
inline 함수를 사용할 경우에 선언을 헤더 파일(확장자 .h)에 두고, 정의를 구현 파일(확장자 .cpp)에서 하면 LNK2019 에러가 생긴다. 이유는 간단하다. 함수를 코드에 인라이닝 한다는것은 inline 함수를 호출한 부분에 해당 inline 함수의 정의를 넣는다는 뜻이다. 그런데 헤더 파일에 함수명만 선언되어 있다면 함수 정의를 인라이닝 할 수 없기 때문에 링크에러가 생기는 것이다. 이 역시 해결책은 간단하다.
inline 함수의 경우에는 헤더 파일에 선언과 정의를 함께 넣어라!
6. template를 사용할 경우에는 선언과 정의를 헤더 파일과 구현 파일로 분리하지 말아라!
5번에서 inline 함수를 설명하다 생각이 난 것인데, C++에서 선언과 정의를 각각의 파일로 분리하면 안 되는 경우가 하나 더 존재한다. 바로 template를 사용할 경우이다. template의 경우에는 동적으로 각각의 형에 맞는 소스 코드를 만들어 내는 방법이므로 선언과 정의를 각각의 파일로 분리해서는 결코 안 된다. 물론, 이 역시 IDE툴을 잘 이용하면 분리할 수 있는 방법이 있지만 그냥 하나의 헤더 파일에 다 구현하기를 추천한다.
자세한 내용은 다음의 링크를 들어가보기를 추천한다.
http://blog.naver.com/sadiles/10046904781
template과 관련된 경우에는 헤더 파일에 선언과 정의를 함께 넣어라!
[ 댓글로 알려주신 LNK2019 케이스 ]
2009년말에 이 글을 쓰면서, 링킹 과정을 개인적으로 다시 한 번 공부했었습니다. 그리고나서부터는 LNK2019로 고생해본적이 거의 없었습니다. 그래서 그런지 케이스를 추가할 일이 별로 없었나 봅니다. 이 글을 다시 본지 오래됐었는데, 많은 분들이 댓글을 달아주셨더군요. 정말 감사합니다. ^^
앞으로는 댓글에 달린 내용도 가능하면 정리해서 이 글에 추가하도록 하겠습니다.
ps - 댓글 달아주신 모든든 분들께 감사드립니다. 복받으실 거에요 ^^
1. 함수를 선언만 하고, 구현하지 않았을 경우! ( by 에몬 & 데비카니 )
LIB 파일 추가 안 한 것과 더불어 링크 에러가 가장 많이 생기는 경우일 것 같습니다. 함수를 선언만 하고, 구현하지 않았을 경우 LNK2019 에러가 발생합니다.
'Programming Error' 카테고리의 다른 글
디버깅시에 브레이크포인트가 걸리지 않을때 (0) | 2013.06.21 |
---|---|
unresolved external symbol이 생기는 이유 (0) | 2013.05.14 |
Direct3DCreate9 관련 에러처리! (0) | 2013.05.14 |
처리되지 않은 예외 xxx 파일이나 어셈블리 xxx또는 여기에 종속 어쩌고 에러.. (0) | 2013.04.24 |