본문 바로가기
Lap

비주얼스튜디오 외부라이블러리 포함시키기

by matters_ 2018. 7. 2.

180702 저번주 금요일부터 깃헙에서 realsense 예제코드를 찾아서 실행해보려 시도중이다.


헤더파일이 포함안되어 해당 출력 파일 폴더를 찾아 속성 > c/c++ > 일반 > 추가 포함 디렉터리와 속성 > 링커 > 일반 > 추가 라이브러리 디렉터리 에 추가 시켰으나 이번엔 링크에러가 뜬다 


심각도 코드 설명 프로젝트 파일 비표시 오류(Suppression) 상태

오류 LNK2019 _rs2_get_librealsense_exception_type 외부 기호(참조 위치: "public: __thiscall rs2::error::error(struct rs2_error *)" (??

0error@rs2@@QAE@PAUrs2_error@@@Z) 함수)에서 확인하지 못했습니다. 627capture D:\project\627capture\627capture\realsence.obj 1



구글신께 도움을 청했고 몇가지 지식은 얻었으나 아직 해결은 못했다. 그중 하나를 보자면


출처 : http://mycpp.blog.me/120147433633

 

template class를 인라인으로 만들관 상관 없지만

함수 밖에 뺀다면 template <typename T>void Stack<T>::함수이름() 형식을 맞춰 줘야 한다.

근데 여기서 주의할 점! template class는 헤더파일과 cpp파일을 분리해서 작성하는 것을 지원하지 않는다.


만약 다음과 같이 한다면 ...


=== stack.h 파일 ====

template <typename T>


class Stack

{

protected:

        int top;

        T m_data[10];

       

public:

        Stack();

        void push(T data);

        void print();

 

};

 

 

 

=== stack.cpp 파일 ====

#include "stack.h"

 

 

template <typename T>Stack<T>::Stack()

{       top = 0;

}

 

template <typename T>void Stack<T>::push(T data)

{

        m_data[top++] = data;

}

 

template <typename T>void Stack<T>::print()

{      

        for(int i=0;i<top;i++)

               cout<<m_data[i]<<"  ";

}

 

 

=== main.cpp 파일 ====

 

#include <iostream>

#include <string>

using namespace std;

 

#include "stack.h"  //stack.cpp로 바꾸지 않으면 에러


void main()

{

        Stack <int>s;

        s.push(10);

        s.push(20);

        s.push(30);

        s.print();

        cout<<endl;

 

        Stack <string>s2;

        s2.push("abc");

        s2.push("def");

        s2.push("ghi");

        s2.print();

        cout<<endl;

 

}


문법상 에러는 없으나 linking 에러 남

오류 1 error LNK2019: "public: void __thiscall Stack<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::print(void)" (?print@?$Stack@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAEXXZ) 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다. main.obj


이유는 template class는 헤더와 cpp파일을 나누는 것을 지원하지 않기 때문이다.
때문에 이렇게 쓰고 싶으면 stack.cpp파일 코드를 긁어서 stack.h 아래 쓰던가,
두개로 나눠서 쓰고 싶다면 main.cpp파일을에서 include "stack.cpp"로 쓰면 된다.


==결과화면==
10  20  30
abc  def  ghi
계속하려면 아무 키나 누르십시오 . . .

[출처] template class 만들때 주의할 점|작성자 수환이


흠.. 비슷한 애러인건 같은데 다른 경우에서 생기는 에러인거 같다 더 찾아보자



더 찾아보니 먼 하위시스템에서 자신이 만들고 있는 프로젝트와 동일하게 설정하면 된다는데 내 경우는 아닌거 같다 더 찾아보자

이경우는 Console 프로젝트 환경에서 메인 함수 이름이 "WinMain()"으로 했을 경우 발생되는 에러라고 한다.



왠지 라이브러리 에러인거 같은데  찾던 도중 뭐하나 제대로 찾았다



 컴파일러가 알려주는 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 에러가 발생합니다.  



출처: http://sadiles.blog.me/10072075057



오 여기서 1번 lib추가 경우를 중점을 두고 lib파일을 찾아서 추가했더니 오류가 122개에서 67개로 줄엇다!!!!!!!!!!!!!!!!!!

 

오류 완전 없에기 가즈아~


그래서 어째어째 찾아서 다 추가 했건만 이제 파일이 손상되어서 읽을 수 없단다..후


심각도 코드 설명 프로젝트 파일 비표시 오류(Suppression) 상태

오류 LNK1107 파일이 잘못되었거나 손상되었습니다. 0x89A에서 읽을 수 없습니다. 627capture D:\project\627capture\librealsense-master\scripts\ubuntu-xenial\ubuntu\opennsl\OpenNSL\sdk-6.5.10-gpl-modules\make\Make.lib 1


... 오만 링크에러는 다 내는듯..


또 구글링하니



The error message suggests, that you have linked against glew32.dll instead of glew32.lib. One always has to link against the lib file and copy the dll to a place where it can be found at runtime.



오류 메시지는 glew32.lib 대신 glew32.dll에 연결되었음을 나타냅니다. 하나는 항상 lib 파일에 링크하고 dll을 런타임에 찾을 수있는 장소에 복사해야합니다. 란다.. 그래서 dll 파일을 찾기로 하였다.

아.. 열이 받으은ㄴ는으아...............

오늘은 여기까지 해야겟다ㅡㅜ






댓글