정적 라이브러리와 공유 라이브러리의 차이점은 무엇입니까?


560

정적 라이브러리와 공유 라이브러리의 차이점은 무엇입니까?

Eclipse를 사용하는데 정적 라이브러리 및 공유 라이브러리를 포함한 여러 프로젝트 유형이 있습니까? 하나는 다른 것보다 장점이 있습니까?


4
Wikipedia에는 정적, 동적 및 공유 라이브러리의 차이점에 대한 설명 이 있습니다.
Adam Holmberg

답변:


745

공유 라이브러리는 .so (또는 Windows .dll 또는 OS X .dylib) 파일입니다. 라이브러리와 관련된 모든 코드는이 파일에 있으며 런타임시이를 사용하는 프로그램에서 참조합니다. 공유 라이브러리를 사용하는 프로그램은 공유 라이브러리에서 사용하는 코드 만 참조합니다.

정적 라이브러리는 .a (또는 Windows .lib) 파일입니다. 라이브러리와 관련된 모든 코드는이 파일에 있으며 컴파일 타임에 프로그램에 직접 연결됩니다. 정적 라이브러리를 사용하는 프로그램은 정적 라이브러리에서 사용하는 코드의 사본을 가져 와서 프로그램의 일부로 만듭니다. [Windows에는 .dll 파일을 참조하는 데 사용되는 .lib 파일도 있지만 첫 번째 파일과 같은 방식으로 작동합니다].

각 방법에는 장단점이 있습니다.

  • 공유 라이브러리는 라이브러리를 사용하는 각 프로그램에서 복제되는 코드의 양을 줄여 바이너리를 작게 유지합니다. 또한 공유 객체를 기능적으로 동등한 객체로 교체 할 수 있지만이를 사용하는 프로그램을 다시 컴파일하지 않고도 성능상의 이점을 추가 할 수 있습니다. 그러나 공유 라이브러리는 라이브러리의 모든 심볼을 사용하는 것과 연결해야하기 때문에 런타임 로딩 비용뿐만 아니라 함수 실행에 대한 추가 비용이 적습니다. 또한 공유 라이브러리를 런타임에 응용 프로그램에로드 할 수 있습니다. 이는 바이너리 플러그인 시스템을 구현하기위한 일반적인 메커니즘입니다.

  • 정적 라이브러리는 이진 파일의 전체 크기를 증가 시키지만 사용중인 라이브러리의 사본을 가지고 다닐 필요는 없습니다. 코드가 컴파일 타임에 연결되므로 추가 런타임로드 비용이 없습니다. 코드는 간단합니다.

개인적으로 공유 라이브러리를 선호하지만 바이너리에 특정 버전의 C ++ 표준 라이브러리 또는 특정 버전의 Boost C ++ 라이브러리와 같이 충족하기 어려운 많은 외부 종속성이 없도록 보장하려면 정적 라이브러리를 사용하십시오.


2
"공유 객체를 기능적으로 동등한 기능으로 대체하지만 성능을 향상시킬 수 있습니다": 구체적으로 API (응용 프로그램 프로그래밍 인터페이스 : 함수 시그니처 및 유형을 포함한 변수)를 의미 적으로 사용하는 호출자 관련 기능이지만 구현 측 기능은 성능과 다를 수 있습니다. 예를 들어, 함수는 항상 파일에 기록합니다-> 또한 $ MY_APP_LOG_SERVER에 예상되는 TCP server : port에 기록합니다.
Tony Delroy

1
"[.sos는 a] 추가로 함수를 실행하기위한 추가 비용이 발생합니다."- 가능합니다 (함수 그룹 / 순서가 정적 링크의 캐시 위치에 대해 최적화 된 경우 또는 크로스와 같은 OS / 로더 / 컴파일러 / 아키텍처의 이상으로 인해 세그먼트 / 대형 포인터 성능 불이익))하지만 많은 아키텍처 / 컴파일러 설정에서 동적 링커는 호출을 패치하여 정확히 동일한 호출기 opcode를 생성합니다.
Tony Delroy

2
"코드가 컴파일 타임에 연결됨에 따라 추가 런타임 로딩 비용이 없습니다. 코드는 간단합니다." -예 및 아니오 ... 실행이 필요한 경우 페이징 될 준비가 된 실행 가능 이미지에 모두 있지만,-프로그램이 캐시에있을 정도로 충분히 최근에 실행되지 않은 상황에서 시작-공유 라이브러리를 사용하는 경우 가능 또는 특정) OS, 드라이버 또는 실행중인 다른 프로그램이 앱에서 사용하려는 동일한 공유 라이브러리를 이미로드했을 것입니다.이 경우 캐시에있을 수 있으며 프로그램이 더 빨리 시작되고 실행됩니다.
Tony Delroy 2013

15
사람들이 언급하지 못한 것은 정적 라이브러리를 사용하면 컴파일러가 응용 프로그램에 필요한 기능을 알고 해당 기능 만 포함하여 최적화 할 수 있다는 것입니다. 라이브러리 크기를 엄청나게 줄일 수 있습니다. 특히 매우 큰 라이브러리의 작은 하위 집합 만 사용하는 경우 더욱 그렇습니다.
jduncanator

1
이 답변은 더 잘 구성 될 수 있습니다. 차이가있는 각 차원의 차이를 표시하기 위해 장단점 또는 표에 대한 글 머리표 목록을 작성하면 도움이됩니다.
ElefEnt

377

정적 라이브러리는 서점과 같고 공유 라이브러리는 ... 라이브러리와 같습니다. 전자와 함께, 당신은 당신의 책 / 기능의 사본을 집으로 가져갑니다; 후자와 함께 당신과 다른 사람들은 같은 책 / 기능을 사용하기 위해 도서관으로갑니다. 따라서 (공유) 라이브러리를 사용하려는 사람은 책 / 기능을 "가져와야"하기 때문에 라이브러리의 위치를 ​​알아야합니다. 정적 라이브러리를 사용하면 책 / 기능을 소유 할 수 있으며 집 / 프로그램 내에 보관할 수 있으며 일단 가지고 있으면 언제 어디서 가져 왔는지 상관하지 않습니다.


70

쉽게 한:

  • 정적 연결 : 하나의 큰 실행 파일
  • 동적 연결 : 작은 실행 파일과 하나 이상의 라이브러리 파일 (Windows의 .dll 파일, Linux의 .so 파일 또는 macOS의 .dylib)

1
이 답변은 실용적이기 때문에 나에게 가장 좋습니다. 컴퓨터에서 실제로 일어나는 일에 대해 이야기하지 않는 은유보다 훨씬 더 의미가 있습니다. 이것이 일어난다는 것을 알고 나면 다른 모든 의미를 직관적으로 알 수 있습니다.
off99555

36

정적 라이브러리의 경우 링커가 라이브러리에서 코드를 추출하여 응용 프로그램을 컴파일 / 빌드하는 시점에서 최종 실행 파일을 빌드하는 데 사용됩니다. 최종 실행 파일은 런타임에 라이브러리에 종속되지 않습니다

공유 라이브러리의 경우, 컴파일러 / 링커는 응용 프로그램이 빌드 될 때 링크하는 이름이 라이브러리에 존재하지만 해당 코드가 응용 프로그램으로 이동하지 않는지 확인합니다. 런타임시 공유 라이브러리를 사용할 수 있어야합니다.

C 프로그래밍 언어 자체에는 정적 또는 공유 라이브러리 개념이 없으며 완전히 구현 기능입니다.

개인적으로 저는 소프트웨어 배포가 더 간단 해지기 때문에 정적 라이브러리를 사용하는 것을 선호합니다. 그러나 이것은 과거에 많은 (피해 적) 피가 흘려 졌다는 의견입니다.


5
"C 프로그래밍 언어 자체에는 정적 라이브러리 또는 공유 라이브러리 개념이 없습니다. 완전히 구현 된 기능입니다."
Tiger

1
안녕하세요 anon / @Tiger, 왜 "C 프로그래밍 언어 자체에는 정적 라이브러리 나 공유 라이브러리 개념이 없습니다. 완전히 구현 된 기능입니까?" 조금 자세하게 설명하거나 적절한 참고 자료를 알려 주시겠습니까?
Sunil Shahu

@SunilShahu 프로그램 컴파일 및 링크 방법은 사용중인 컴파일러 및 링커, 즉 언어의 특정 구현에 따라 다릅니다. 언어 보급은 일반적으로 언어를 구현 또는 구축하는 방법을 설명하지 않으며 기능, 구문, 문법 등 만 설명합니다.
JC Rocamonde

@SunilShahu보다 명백한 예는 JavaScript (예 : 사양 (EcmaScript)가 언어의 기능을 설명하지만 JS 인터프리터 (예 : 브라우저 엔진 또는 Node.js)를 제공하는 다른 공급 업체) 일 수 있습니다. 반면에, 파이썬 프로그래밍 언어는 여러 가지 구현이 있습니다. 공식적인 것은 CPython이지만 다른 언어로 작성된 다른 것도 있습니다.
JC Rocamonde

31

정적 라이브러리는 응용 프로그램의 일부로 컴파일되는 반면 공유 라이브러리는 컴파일되지 않습니다. 공유 라이브러리에 의존하는 응용 프로그램을 배포 할 때 라이브러리 (예 : MS Windows에 dll을 설치해야합니다.

정적 라이브러리의 장점은 응용 프로그램을 실행하는 사용자에게 필요한 종속성이 없다는 것입니다. 예를 들어 DLL을 업그레이드 할 필요가 없습니다. 단점은 필요한 모든 라이브러리와 함께 제공되므로 응용 프로그램의 크기가 더 크다는 것입니다.

더 작은 응용 프로그램으로 이어질뿐만 아니라 공유 라이브러리는 사용자에게 응용 프로그램의 일부인 라이브러리에 의존하지 않고 더 나은 버전의 라이브러리를 사용할 수있는 기능을 제공합니다.


3
알려진 DLL 지옥
gheese

1
"정적 라이브러리는 응용 프로그램의 일부로 컴파일됩니다"... 정적 라이브러리는 정적 라이브러리로 컴파일되고 응용 프로그램의 일부로 링크됩니다
idclev 463035818

19

공유 라이브러리의 가장 큰 장점은 라이브러리를 사용하는 프로세스 수에 관계없이 메모리에로드 된 코드 사본이 하나만 있다는 것입니다. 정적 라이브러리의 경우 각 프로세스는 자체 코드 사본을 얻습니다. 이로 인해 상당한 메모리 낭비가 발생할 수 있습니다.

정적 라이브러리의 장점 인 OTOH는 모든 것이 애플리케이션에 번들로 제공된다는 것입니다. 따라서 클라이언트가 자신의 시스템에서 올바른 라이브러리 (및 버전)를 사용할 수 있다고 걱정할 필요가 없습니다.


1
정적 라이브러리를 사용할 때 디스크와 메모리에서 실행 가능 이미지가 더 큽니다.
JustJeff

맞습니다. 모든 것이 응용 프로그램에 번들로 제공되었다고 말했을 때 언급 한 내용입니다.
Jasmeet

또한 .so* nix 시스템의 파일은 일종의 공유 (동적) 라이브러리입니다.
snr

6

다른 모든 답변 외에도 아직 언급되지 않은 것은 디커플링입니다.

내가 다루고있는 실제 생산 코드에 대해 말씀 드리겠습니다.

300 개가 넘는 프로젝트 (Visual Studio 사용)로 구성된 매우 큰 소프트웨어는 주로 정적 lib로 빌드되고 결국 하나의 거대한 실행 파일로 모두 연결되므로 다음과 같은 문제가 발생합니다.

-링크 시간이 매우 깁니다. 10 분의 컴파일 시간을 말하면 15 분 이상의 링크가 생길 수 있습니다. 일부 도구는 코드를 계측해야하는 메모리 검사 도구와 같은 큰 실행 파일이 있습니다. 바보로 여겨지는 한계에 도달 할 수 있습니다.

더 실제적인 예에서, 모든 프로젝트의 헤더 파일은 다른 프로젝트에서 접근 할 수 있습니다. 결과적으로 한 개발자가 종속성을 추가하는 것이 매우 쉬웠습니다. 끝에 링크가 심볼을 찾기 때문에 헤더를 포함하는 것입니다. 그것은 끔찍한 사이클링 종속성과 완전한 혼란으로 끝납니다.

공유 라이브러리를 사용하면 개발자가 종속 라이브러리를 추가하기 위해 프로젝트 빌드 시스템을 편집해야하기 때문에 약간의 추가 작업이 필요합니다. 공유 라이브러리 코드가 더 깨끗한 코드 API를 제공하는 경향이 있음을 관찰했습니다.


2
-------------------------------------------------------------------------
|  +-  |    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  |                                     |
-------------------------------------------------------------------------
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.