동적(Dynamic) & 정적(Static) 라이브러리
이 두 가지 개념을 이해하기 전에 우선 라이브러리에 대한 개념을 확인해야 한다.
라이브러리(Library)란?
소프트웨어를 만들 때 쓰이는 클래스나 서브루틴[1] 들의 모임을 가리키는 말이다.
다른 프로그램들과 링크되기 위해 존재하는, 하나 이상의 서브루틴이나 함수(Function)들의 집합 파일이다.
또한, 링크될 수 있도록 보통 컴파일 된 형태인 목적코드(Object Code)[2] 형태로 존재한다.
미리 컴파일 되어 있어서 컴파일 시간도 단축된다.
라이브러리의 목적
라이브러리는 코드 재사용을 위해 조직화된 초창기 방법 중의 하나이며 많은 다른 프로그램들에서 사용할 수 있도록 운영체제나 소프트웨어 개발 환경제공자들에 의해 제공되는 경우가 많다.
라이브러리 내에 있는 루틴들은 범용적으로 사용도 가능하며 3차원 애니메이션 그래픽 등과 같이 특별한 용도의 함수로 설계될 수도 있다.
라이브러리들은 사용자의 프로그램과 링크되어 실행이 가능한 완전한 프로그램을 이룬다.
라이브러리의 구분
라이브러리는 두 가지로 구분이 가능하다.
동적 라이브러리 : 완성된 프로그램을 실행할 때 포함시키는 라이브러리
정적 라이브러리 : 프로그램을 컴파일하는 과정에서 포함시키는 오브젝트 파일들의 모임
이는 동적 / 정적 할당과 비슷한 구분으로 컴파일 과정에서 포함이 되는 라이브러리를 정적 라이브러리, 런타임 시 포함시키는 라이브러리가 동적 라이브러리이다.
참고) 윈도우와 리눅스의 라이브러리는 확장자명이 다르다.
동적 라이브러리(Dynamic Library)
동적 라이브러리는 구현하고 컴파일을 하게 되면 정적 라이브러리와는 다르게 Output File이 2개가 생성된다.
하나는 *.dll이고 다른 하나는 *.lib이다. 여기서 *.lib는 정적 라이브러리의 확장자명과는 전혀 다르다.
정적 라이브러리의 *.lib 파일은 라이브러리 전체 코드를 포함하는 바이너리이며, DLL의 *.lib 파일은 DLL이 제공하고자 하는 함수 정보(함수명)을 가지는 정보 파일이다.
à 추측) 함수의 선언만 되어 있는 파일로 정의부는 다른 곳에 있을 거로 예상
프로그램을 시작할 때 같이 로딩되어 프로그램을 종료할 때 메모리에서 해제되는 방법을 암시적 링킹(Implicit Linking)[3] 이라 한다.
DLL의 *.lib 파일을 이용하여 링킹하는 것을 암시적 링킹이라고 한다.
프로그램 실행 시 필요할 경우에만 외부 DLL 파일에서 함수를 참조한다. 링크 단계에서 실행 프로그램의 *.obj 파일들과 DLL의 *.lib 파일을 함께 링크하여 이 정보를 토대로 런타임 도중에 DLL의 함수코드를 참조하게 되는 것이다.
즉, *.lib는 링크 시 필요하고, *.dll 파일은 실행 시 필요하다.
동적 라이브러리의 장점
메모리를 절약하고 스와핑을 줄인다. 프로그램이 한 번 메모리에 올려진 것을 공유하므로 메모리 사용 공간이 정적 라이브러리에 비해 적다.
여러 프로세스가 메모리에 있는 하나의 DLL 복사본을 공유하여 하나의 DLL을 동시에 사용할 수 있다.
반면, 정적 연결 라이브러리를 사용하여 빌드 된 응용 프로그램의 경우 Windows는 각 응용 프로그램에 대해 하나의 라이브러리 코드 복사본을 메모리에 로드해야 한다.
DLL은 메모리에 올라와 있는 DLL을 참조하여 사용하기 때문에 하나의 라이브러리만 있으면 되지만 정적은 빌드 시 라이브러리를 함께 컴파일하여야 하기 때문에 각 프로그램마다 라이브러리 코드를 갖고 있게 된다.
DLL을 보다 쉽게 업그레이드할 수 있다.
DLL의 함수가 변경되어도 이 함수의 인수 및 반환 값이 변경되지 않았으면 그 함수를 사용하는 응용 프로그램은 다시 컴파일하거나 링크할 필요가 없다.
반면, 정적으로 링크되는 개체 코드의 경우에는 함수가 변경되면 응용 프로그램을 다시 링크 시켜야 한다.
à 추측) 이는 컴파일 이전에 링크가 되는 라이브러리이기 때문에 변경이 될 경우 매번 새로 컴파일해야 하는 것으로 생각됨.
같은 맥락으로 프로그램 출시 후 지원이 가능하다.
예를 들어, 응용 프로그램을 출시할 때 사용할 수 없었던 디스플레이 기능을 지원하도록 디스플레이 드라이버 DLL을 수정할 수 있다.
또한 비슷한 맥락으로 프로그램 변경 시 변경된 부분의 공유 라이브러리만 재배포하면 되므로 유지보수가 쉽다.
언어 형식이 다른 여러 프로그램을 지원한다.
서로 다른 프로그래밍 언어로 작성된 프로그램인 경우에도 함수의 호출 규칙을 따르면 여러 프로그램에서 동일한 DLL 함수를 호출할 수 있다.
이 경우 각 프로그램과 DLL 함수는 여러가지 면(스택에 해당 함수의 인수가 들어가는 순서, 스택을 정리하는 것이 함수인지 응용 프로그램인지의 여부 및 인수가 레지스터에 전달되는 지의 여부)에서 호환될 수 있어야 한다.
동적 라이브러리의 단점
외부 의존도가 생기기 때문에 이식성[4] 이 어렵다.
공유 라이브러리를 메모리에 올리려면 찾고 올리는데 시간이 걸리므로 성능저하가 생긴다.
정적 라이브러리(Static Library)
프로그램 빌드 시에 라이브러리가 제공하는 코드를 실행 파일에 넣는 방식의 라이브러리를 의미한다. 즉, 컴파일 이전 단계에서 적용되는 라이브러리이다.
컴파일의 링킹 단계에서 실행 파일에 결합된다.
특정 기능의 라이브러리를 정적으로 제작한다는 것은 컴파일의 Link 단계에서 실행 프로그램에 포함되게 한다는 의미이다. 따라서 런타임시에 추가로 포함하거나 할 수 없다.
즉 라이브러리의 동작 코드가 이를 사용하는 실행 프로그램 속에 포함되기 때문에 별도의 추가 작업 없이, 그리고 독립적으로 라이브러리 함수를 사용할 수 있다.
정적 라이브러리를 사용하여 컴파일을 하면 링커가 프로그램이 필요로 하는 부분을 라이브러리에서 찾아 실행 파일에 바로 복사한다.
실행 파일 내부에 들어가 있기 때문에 실행 시 라이브러리가 필요 없다.
정적 라이브러리의 장점
시스템 환경이 변해도 애플리케이션에 아무런 영향이 없고, 완성된 애플리케이션을 안정적으로 사용할 수 있다.
컴파일 시 필요한 라이브러리를 프로그램 내에 적재하기 때문에 이식성이 좋다.
런타임 시 외부를 참조할 필요가 없기 때문에 속도에서 동적 라이브러리보다 앞선다.
정적 라이브러리의 단점
같은 코드를 가진 여러 프로그램을 실행할 경우 코드가 중복이 되니 그만큼 메모리를 낭비하게 된다.
라이브러리 변경이 필요할 시, 변경된 라이브러리만 재배포하면 안 되고 프로그램을 다시 재배포해야 한다.
'프로그래밍 > 공부' 카테고리의 다른 글
[Game] 객체의 회전 (0) | 2022.12.19 |
---|---|
[Game] 변환행렬 (2) | 2022.12.15 |
[Game] Delta Time (0) | 2022.12.14 |
[C++] 싱글턴 패턴 (0) | 2022.12.13 |
[C++] 정적(Static) 변수 (0) | 2022.12.13 |
댓글