C, C++ 외부 라이브러리(dll, lib) 사용하기

Home

Import Dynamic or Static Library By Visual Studio

목차

mosquitto나 ifcplusplused 같은 오픈소스를 Build 하기 위해 많은 노력을 했었는데 그 과정에서 얻게 된 지식을 공유하기 위해 작성하였습니다.

dll, lib

dll과 lib은 무엇일까?

먼저 무엇인지 말하면 dll은 동적 라이브러리이고, lib은 정적 라이브러리입니다.
외부의 코드를 사용하기 위한 Library라고 생각하시면 됩니다. dll은 Runtime 중에, lib은 Compile 할 때 필요합니다.


lib

일반적으로 실행 파일을 만들 때는 소스 코드를 컴파일하고 만들어진 obj 파일을 링커가 하나로 묶어 exe 파일을 만듭니다. 여기서 lib을 사용하면 링크 단계에서 링커가 이 lib파일도 같이 묶어서 하나의 exe 파일을 만들게 됩니다.

쉽게 말하면 우리가 컴파일에 성공해 만들어지는 exe 파일 안에 lib의 내용이 모두 들어가게 됩니다.

우리가 일반적으로 쓰는 stdio.h 같은 코드 덩어리도 실제 선언한 곳에 전부 들어가 있게 됩니다. 그렇기 때문에 많이 쓰이면 쓰일수록 파일이 무거워지게 되며, RAM에 메모리가 많이 올라가게 됩니다.

미리 컴파일된 헤더 pch와의 차이는??

pch는 말 그대로 전처리기가 헤더 파일의 내용을 가져와서 컴파일러가 그 내용을 컴파일하지만, lib은 이미 컴파일된 obj 파일을 가지고 링커가 연결만 시켜줍니다.

또한 pch는 사용하고자 하는 곳에 모두 명시를 해야 하지만, lib은 하지 않아도 괜찮습니다. 다만 아까 말했듯이 많이 사용한다면 파일의 크기가 커지는 단점이 있습니다. -> (이러한 단점을 해결하기 위해 dll이 나왔습니다.)

내 소스에 적용하기

lib을 만들고 해당 소스를 외부의 다른 프로젝트에서 사용하려면 필요한 것은 2가지가 있습니다.

  1. 링커에게 해당 lib의 경로를 알려준다.
  2. 해당 include(header)의 경로를 알려준다.

직접 자신의 소스 파일에 적용하는 방법은 뒤에서 진행하도록 하겠습니다.


dll

  • Link 단계에서 동적으로 라이브러리 파일을 추가합니다.

dlllib과 달리 파일을 실행할 때 해당 링커가 dll의 위치를 알고 있다면 exe 파일에 내용이 포함되어 있지 않아도 실행이 가능합니다.

즉 동적인 링킹이 가능합니다. (dll은 프로세스의 주소 공간에 동적으로 로드가 가능하게 만들어져있기 때문입니다.)

동적 링킹으로 인한 장점은?

  • 실행 파일의 메모리 절약이 가능합니다.
  • RAM 메모리 절약 또한 가능합니다. 2개 이상의 파일에서 하나의 dll 파일을 사용할 때 RAM에는 하나의 dll 파일만 올라가게 됩니다.
  • 그 밖에도 여러 가지가 있지만 현재 게시글에서 필요한 내용만 적도록 하겠습니다.

링킹의 방법

dll은 프로세스의 주소 공간에 로드 되어야만 사용될 수 있는데, 로드 되는 방법에는 2가지가 있습니다.

  • 암시적 링킹

실행 파일 자체에 어떤 dll의 어떤 함수를 사용하겠다는 정보를 포함시키고 운영체제가 프로그램 실행 시 해당 함수들을 초기화한 후 그것을 이용하는 방법입니다.

  • 명시적 링킹

프로그램이 실행 중일 때 dll 파일이 있는지 검사하고 동적으로 원하는 함수만 불러와서 쓰는 방법입니다.

현 게시글은 외부 라이브러리를 Import 하기 위한 내용이므로, 각 링킹의 정확한 방법은 밑의 참고에서 확인하시기 바랍니다.

dll 파일의 사용

명시적 링킹은 설명한 그대로 직접 코드를 통해 원하는 함수만 불러와서 사용하는 방법입니다. 더 구체적으로 말하면 함수 포인터를 얻어와서 사용하는 방법입니다. 일반적인 오픈 소스에서는 이런 방식을 이용하지 않고 암시적 링킹을 통해 제공하기 때문에 암시적 링킹에 대한 설명 방법을 알려드리도록 하겠습니다.

암시적 링킹의 방법을 통해 dll 파일을 생성할 경우 총 2개의 파일이 만들어지게 됩니다. 하나는 *.dll이고, 다른 하나는 *.lib입니다. 여기서 만들어진 lib 파일은 위에서 설명한 정적 라이브러리가 아니라 dll을 통해 불러들일 함수가 들어있습니다.

내 소스에 적용하기

dll에서는 lib과 다르게 필요한 것이 총 3가지입니다.

  1. lib 파일 (위의 정적 라이브러리 x)
  2. include(header) 파일
  3. dll 파일

여기서 중요한 것은! dll 파일은 lib과 다르게, Compile과 실행에 필요한 것이 다르다는 것입니다.

  • Compile 하기

Compile 할 때는 lib과 마찬가지로 링커에게 해당 lib의 경로를 알려준 후, 해당 헤더 파일(include)의 경로를 알려주면 Compile에 성공합니다. 하지만 실행하려 할 경우 해당 dll이 없다며 실패합니다. 해당 함수의 실체인 dll을 exe 파일이 모르기 때문입니다.

  • 실행하기

따라서 해당 파일을 실행하기 위해선 exe 파일이 실행할 때 필요한 dll 파일을 연결해줘야 합니다.

  • lib(정적 라이브러리)는 실행에 필요한 과정이 없을까?

위에서 주의 깊게 읽으셨다면 잘 알겠지만 lib(정적 라이브러리)의 경우에는 해당 파일의 실체가 다 exe 파일 안에 들어가게 됩니다.



내 프로젝트에 각종 오픈 소스 적용하기

어떤 소스를 적용하던 크게 2가지만 생각하시면 됩니다.

  1. 만약 Compile만 하기 위해 Compile 과정만 거쳤다면 Compile에는 성공하지만 실행은 되지 않습니다.

  2. Compile 과는 별개로 실행만을 목적으로 하고 있다면 따로 lib과 include 파일을 연결하지 않아도 exe 파일 안에 dll 파일만 넣을 경우 실행에 성공하게 됩니다.

따라서 직접 오픈 소스를 적용하여 테스트하고 싶다면 Compile 하기 위한 lib, include 파일 그리고 실행하기 위해선 dll 파일이 모두 필요합니다.

Visual Studio 기준으로 각 파일을 링크하는 방법입니다. 예제는 ptrhead입니다.

Compile

Compile 하기 위해선 lib파일과 include(header) 파일이 필요합니다.

lib

  • 링커 > 일반 > 추가 라이브러리 디렉터리

해당 lib 파일의 경로를 입력해줍니다.

setting


  • 링커 > 입력 > 추가 종속성

해당 lib 파일의 파일명을 입력해줍니다.

setting


include

  • C/C++ > 일반 > 추가 포함 디렉터리

해당 헤더 파일의 경로를 입력해줍니다.

setting


실행

dll

해당 dll 파일의 경로를 입력해줍니다.

setting


예제 pthread 연습해보기

예제인 pthread를 직접 사용하기위해 Compile 하여 실행해본다면 더 이해가 빠르게 될 수 있습니다. 다음 url은 Window 환경에서 Visual Studio를 이용해 pthread를 사용하는 방법입니다.


그밖에…

각 파일을 링크하는 속성 창 중에 VC++ 디렉토리에도 비슷한 것이 있습니다.

  • VC++ 디렉터리 > 포함 디렉터리
  • VC++ 디렉터리 > 라이브러리 디렉터리

다음의 2가지는 Visual Studio의 기본 lib과 include 파일을 설정해주는 부분입니다. 추가적인 작업을 할 때는 제가 설명해준 방법대로 하시면 됩니다.

저도 헷갈려서 mosquitto Build 과정을 위와 섞어서 사용하였는데 추후에 고치도록 하겠습니다.


정리하자면 다음과 같습니다.

setting



참고