[Library] Dynamic vs. Static Library


분명 학부시절에 배웠던것 같기도 한데… iOS 업무를 진행하다보니, 동적/정적 라이브러리라는 개념이 나와서 헷갈렸다. 이에 대해 정리해보고, 온전히 내것으로 만들어보자 !

동적라이브러리 VS 정적라이브러리

정적라이브러리

Static Library(Static Link Library)

일반적으로 우리가 말하는 라이브러리입니다. 컴파일타임에 컴파일러나 링커/바인더에 의해서 타겟 프로그램으로 복사되어서 오브젝트 파일을 만들고, 실행파일을 만들게 됩니다.

이러한 과정을 정적인 빌드 과정(Static Build)라고 합니다.

정적라이브러리는 이 빌드/링크 과정에서 다른 정적인 라이브러리와 오브젝트 파알들과 합쳐져서 하나의 실행파일로 만들어지거나, 정적인 메모리공간에 적재되어서 실행되는 동안에 불려지기도 합니다.

정적라이브러리를 사용하기위해서는 프로젝트 설정의 Link 옵션에 라이브러리를 추가해주거나, 아래의 #pragma 지시자를 사용하면 됩니다.

#pragma comment(lib, "NAME.lib")

장점

해당 응용프로그램이 모든 라이브러리가 존재하고 올바른 버전이라는 것을 확신 할 수 있습니다. 즉, 의존성 문제를 해결합니다.

프로그램을 배포시에 배포/설치 과정을 매우 단순화 시켜주어서, 하나의 실행파일만 제공하게 합니다.

Static Link(정적연결)에서는 직/간접적으로 타겟 실행파일(or 타겟 라이브러리)에서 참조되는 라이브러리의 일부만 포함합니다.

단점

실행파일의 크기가 라이브러리 코드를 별도 파일에 저장하지 않고, 전부 실행파일에 포함하고 있기 때문에 동적 라이브러리를 사용할 때 보다, 큽니다. 즉, 실행파일의 크기가 큰 만큼 전체 실행파일이 메모리에 올라가게 됩니다.(하지만 전체가 올라가있는 만큼, 라이브러리를 메모리에 올리고 내리는 로드는 걸리지않습니다.)

동적라이브러리(Dynamic (Linking) Library : DLL)

동적으로 링크하여 사용하는 라이브러리입니다.

동적라이브러리는 이것을 사용하고자하는 실행 바이너리에서 필요시에만 사용할 수 있도록 최소한의 정보만 포함하여 링크하거나 아예 독립적으로 DLL을 로드하고 사용하고 해제합니다.

동적라이브러리를 컴파일하면, Static Library와는 다르게 2개의 파일(Output File)이 생성됩니다.

  1. *.lib 파일 : 정적라이브러리의 *.lib 와는 다른 파일입니다.
    • 정적라이브러리의 *.lib 파일은 라이브러리 전체 코드를 포함하는 바이너리입니다.
    • 동적라이브러리의 *.lib 파일은 DLL 이 제공하고자 하는 함수정보(함수명)을 가지는 정보 파일입니다.
  2. *.dll 파일 : *.lib파일로 링크되었다면 *.dll 파일은 실행시 필요한 파일입니다. 즉 런타임에 DLL의 함수코드를 참조하게 됩니다.

링킹의 방식

  1. implicit linking
    • *.lib / *.dll 파일을 생성하는 방식을 암시적 링킹이라고 합니다.
  2. explicit linking
    • 명시적 링킹에서는 *.lib 파일이 생성되지 않습니다. 실행 바이너리 링크단계에서 dll 의 함수정보가 필요하지 않기 때문입니다.
    • 명시적 링킹에서 사용되는 세가지 함수는 다음과 같습니다.
      1. LoadLibrary : 필요한 dll을 프로세스 가상 메모리에 매핑하게됩니다.
      2. GetProcAddress : dll 함수의 포인터를 획득합니다.
      3. FreeLibrary : 프로세스 가상 메모리에서 dll 을 반환합니다.
    • 프로세스는 내부적으로 dll의 레퍼런스 카운트를 계산합니다.
      • 즉, LoadLibarary 호출 시, reference count 를 +1 시키고, FreeLibrary시 -1을 시키게 됩니다. Reference Count 가 0이 될 때, 프로세스 가상 메모리에서 해당 dll은 해제가 됩니다.
      • 중요한 것은, 가상메모리에서의 해제이지, 실제 물리 메모리에서의 해제는 아니라는 점입니다.

공유라이브러리(Shared Libray)

  • 공유라이브러리는 실행파일들이 같은 라이브러리 파일을 공유하는 형태를 띠는 것을 말합니다.
  • 대부분의 최신의 OS 들은 이렇게 바이너리 실행 파일들이 같은 라이브러리를 공유할 수 있도록 합니다.