답변:
공유 라이브러리는 .so (또는 Windows .dll 또는 OS X .dylib) 파일입니다. 라이브러리와 관련된 모든 코드는이 파일에 있으며 런타임시이를 사용하는 프로그램에서 참조합니다. 공유 라이브러리를 사용하는 프로그램은 공유 라이브러리에서 사용하는 코드 만 참조합니다.
정적 라이브러리는 .a (또는 Windows .lib) 파일입니다. 라이브러리와 관련된 모든 코드는이 파일에 있으며 컴파일 타임에 프로그램에 직접 연결됩니다. 정적 라이브러리를 사용하는 프로그램은 정적 라이브러리에서 사용하는 코드의 사본을 가져 와서 프로그램의 일부로 만듭니다. [Windows에는 .dll 파일을 참조하는 데 사용되는 .lib 파일도 있지만 첫 번째 파일과 같은 방식으로 작동합니다].
각 방법에는 장단점이 있습니다.
공유 라이브러리는 라이브러리를 사용하는 각 프로그램에서 복제되는 코드의 양을 줄여 바이너리를 작게 유지합니다. 또한 공유 객체를 기능적으로 동등한 객체로 교체 할 수 있지만이를 사용하는 프로그램을 다시 컴파일하지 않고도 성능상의 이점을 추가 할 수 있습니다. 그러나 공유 라이브러리는 라이브러리의 모든 심볼을 사용하는 것과 연결해야하기 때문에 런타임 로딩 비용뿐만 아니라 함수 실행에 대한 추가 비용이 적습니다. 또한 공유 라이브러리를 런타임에 응용 프로그램에로드 할 수 있습니다. 이는 바이너리 플러그인 시스템을 구현하기위한 일반적인 메커니즘입니다.
정적 라이브러리는 이진 파일의 전체 크기를 증가 시키지만 사용중인 라이브러리의 사본을 가지고 다닐 필요는 없습니다. 코드가 컴파일 타임에 연결되므로 추가 런타임로드 비용이 없습니다. 코드는 간단합니다.
개인적으로 공유 라이브러리를 선호하지만 바이너리에 특정 버전의 C ++ 표준 라이브러리 또는 특정 버전의 Boost C ++ 라이브러리와 같이 충족하기 어려운 많은 외부 종속성이 없도록 보장하려면 정적 라이브러리를 사용하십시오.
정적 라이브러리는 서점과 같고 공유 라이브러리는 ... 라이브러리와 같습니다. 전자와 함께, 당신은 당신의 책 / 기능의 사본을 집으로 가져갑니다; 후자와 함께 당신과 다른 사람들은 같은 책 / 기능을 사용하기 위해 도서관으로갑니다. 따라서 (공유) 라이브러리를 사용하려는 사람은 책 / 기능을 "가져와야"하기 때문에 라이브러리의 위치를 알아야합니다. 정적 라이브러리를 사용하면 책 / 기능을 소유 할 수 있으며 집 / 프로그램 내에 보관할 수 있으며 일단 가지고 있으면 언제 어디서 가져 왔는지 상관하지 않습니다.
정적 라이브러리의 경우 링커가 라이브러리에서 코드를 추출하여 응용 프로그램을 컴파일 / 빌드하는 시점에서 최종 실행 파일을 빌드하는 데 사용됩니다. 최종 실행 파일은 런타임에 라이브러리에 종속되지 않습니다
공유 라이브러리의 경우, 컴파일러 / 링커는 응용 프로그램이 빌드 될 때 링크하는 이름이 라이브러리에 존재하지만 해당 코드가 응용 프로그램으로 이동하지 않는지 확인합니다. 런타임시 공유 라이브러리를 사용할 수 있어야합니다.
C 프로그래밍 언어 자체에는 정적 또는 공유 라이브러리 개념이 없으며 완전히 구현 기능입니다.
개인적으로 저는 소프트웨어 배포가 더 간단 해지기 때문에 정적 라이브러리를 사용하는 것을 선호합니다. 그러나 이것은 과거에 많은 (피해 적) 피가 흘려 졌다는 의견입니다.
정적 라이브러리는 응용 프로그램의 일부로 컴파일되는 반면 공유 라이브러리는 컴파일되지 않습니다. 공유 라이브러리에 의존하는 응용 프로그램을 배포 할 때 라이브러리 (예 : MS Windows에 dll을 설치해야합니다.
정적 라이브러리의 장점은 응용 프로그램을 실행하는 사용자에게 필요한 종속성이 없다는 것입니다. 예를 들어 DLL을 업그레이드 할 필요가 없습니다. 단점은 필요한 모든 라이브러리와 함께 제공되므로 응용 프로그램의 크기가 더 크다는 것입니다.
더 작은 응용 프로그램으로 이어질뿐만 아니라 공유 라이브러리는 사용자에게 응용 프로그램의 일부인 라이브러리에 의존하지 않고 더 나은 버전의 라이브러리를 사용할 수있는 기능을 제공합니다.
공유 라이브러리의 가장 큰 장점은 라이브러리를 사용하는 프로세스 수에 관계없이 메모리에로드 된 코드 사본이 하나만 있다는 것입니다. 정적 라이브러리의 경우 각 프로세스는 자체 코드 사본을 얻습니다. 이로 인해 상당한 메모리 낭비가 발생할 수 있습니다.
정적 라이브러리의 장점 인 OTOH는 모든 것이 애플리케이션에 번들로 제공된다는 것입니다. 따라서 클라이언트가 자신의 시스템에서 올바른 라이브러리 (및 버전)를 사용할 수 있다고 걱정할 필요가 없습니다.
.so
* nix 시스템의 파일은 일종의 공유 (동적) 라이브러리입니다.
다른 모든 답변 외에도 아직 언급되지 않은 것은 디커플링입니다.
내가 다루고있는 실제 생산 코드에 대해 말씀 드리겠습니다.
300 개가 넘는 프로젝트 (Visual Studio 사용)로 구성된 매우 큰 소프트웨어는 주로 정적 lib로 빌드되고 결국 하나의 거대한 실행 파일로 모두 연결되므로 다음과 같은 문제가 발생합니다.
-링크 시간이 매우 깁니다. 10 분의 컴파일 시간을 말하면 15 분 이상의 링크가 생길 수 있습니다. 일부 도구는 코드를 계측해야하는 메모리 검사 도구와 같은 큰 실행 파일이 있습니다. 바보로 여겨지는 한계에 도달 할 수 있습니다.
더 실제적인 예에서, 모든 프로젝트의 헤더 파일은 다른 프로젝트에서 접근 할 수 있습니다. 결과적으로 한 개발자가 종속성을 추가하는 것이 매우 쉬웠습니다. 끝에 링크가 심볼을 찾기 때문에 헤더를 포함하는 것입니다. 그것은 끔찍한 사이클링 종속성과 완전한 혼란으로 끝납니다.
공유 라이브러리를 사용하면 개발자가 종속 라이브러리를 추가하기 위해 프로젝트 빌드 시스템을 편집해야하기 때문에 약간의 추가 작업이 필요합니다. 공유 라이브러리 코드가 더 깨끗한 코드 API를 제공하는 경향이 있음을 관찰했습니다.
-------------------------------------------------------------------------
| +- | Shared(dynamic) | Static Library (Linkages) |
-------------------------------------------------------------------------
|Pros: | less memory use | an executable, using own libraries|
| | | ,coming with the program, |
| | | doesn't need to worry about its |
| | | compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of | bigger memory uses |
| | libraries may be altered | |
| | subject to OS and its | |
| | version, which may affect| |
| | the compilebility and | |
| | runnability of the code | |
-------------------------------------------------------------------------