Sự khác biệt giữa thư viện tĩnh và chia sẻ?


560

Sự khác biệt giữa các thư viện tĩnh và chia sẻ là gì?

Tôi sử dụng Eclipse và có một số loại dự án bao gồm Thư viện tĩnh và Thư viện chia sẻ? Có ai có lợi thế hơn người kia không?


4
Wikipedia có một mô tả tốt về sự khác biệt giữa các thư viện tĩnh, động và chia sẻ.
Adam Holmberg

Câu trả lời:


745

Các thư viện được chia sẻ là các tệp .so (hoặc trong Windows. Hoặc trong tệp OS X .dylib). Tất cả các mã liên quan đến thư viện đều nằm trong tệp này và nó được tham chiếu bởi các chương trình sử dụng nó trong thời gian chạy. Một chương trình sử dụng thư viện dùng chung chỉ tạo tham chiếu đến mã mà nó sử dụng trong thư viện dùng chung.

Thư viện tĩnh là các tệp .a (hoặc trong Windows .lib). Tất cả các mã liên quan đến thư viện nằm trong tệp này và nó được liên kết trực tiếp vào chương trình tại thời điểm biên dịch. Một chương trình sử dụng thư viện tĩnh lấy các bản sao của mã mà nó sử dụng từ thư viện tĩnh và biến nó thành một phần của chương trình. [Windows cũng có các tệp .lib được sử dụng để tham chiếu các tệp dll, nhưng chúng hoạt động giống như tệp đầu tiên].

Có những ưu điểm và nhược điểm trong từng phương pháp:

  • Thư viện dùng chung giảm số lượng mã được sao chép trong mỗi chương trình sử dụng thư viện, giữ cho các nhị phân nhỏ. Nó cũng cho phép bạn thay thế đối tượng chia sẻ bằng một đối tượng tương đương về chức năng, nhưng có thể đã thêm các lợi ích hiệu năng mà không cần phải biên dịch lại chương trình sử dụng nó. Tuy nhiên, các thư viện dùng chung sẽ có một chi phí bổ sung nhỏ để thực hiện các chức năng cũng như chi phí tải thời gian chạy vì tất cả các biểu tượng trong thư viện cần được kết nối với những thứ chúng sử dụng. Ngoài ra, các thư viện dùng chung có thể được tải vào một ứng dụng vào thời gian chạy, đây là cơ chế chung để thực hiện các hệ thống trình cắm thêm nhị phân.

  • Thư viện tĩnh tăng kích thước tổng thể của nhị phân, nhưng điều đó có nghĩa là bạn không cần mang theo bản sao của thư viện đang được sử dụng. Vì mã được kết nối tại thời điểm biên dịch, không có bất kỳ chi phí tải thời gian chạy bổ sung nào. Mã chỉ đơn giản là có.

Cá nhân, tôi thích các thư viện dùng chung, nhưng sử dụng các thư viện tĩnh khi cần đảm bảo rằng nhị phân không có nhiều phụ thuộc bên ngoài có thể khó đáp ứng, chẳng hạn như các phiên bản cụ thể của thư viện chuẩn C ++ hoặc các phiên bản cụ thể của thư viện Boost C ++.


2
"thay thế đối tượng được chia sẻ bằng ... tương đương về mặt chức năng, nhưng có thể [cải thiện] hiệu suất": cụ thể, chức năng đối mặt với người gọi tương đương trong việc sử dụng API ngữ nghĩa (giao diện lập trình ứng dụng: chữ ký hàm và biến bao gồm các loại), nhưng phía triển khai chức năng có thể khác nhau nhiều hơn perf.: vd: chức năng luôn ghi vào tệp -> cũng đăng nhập vào máy chủ TCP: cổng dự kiến ​​trong $ MY_APP_LOG_SERVER.
Tony Delroy

1
"[.sos phải chịu một] chi phí bổ sung nhỏ để thực hiện các chức năng" - điều đó là có thể (nếu các nhóm chức năng / thứ tự đã được tối ưu hóa cho vị trí bộ đệm trong liên kết tĩnh hoặc do sự kỳ lạ trong hệ điều hành / trình tải / trình biên dịch / kiến ​​trúc như chéo -sự phán quyết / hình phạt hoàn hảo của con trỏ lớn), nhưng trên nhiều kiến ​​trúc / cài đặt trình biên dịch, trình liên kết động sẽ vá lỗi cuộc gọi để tạo ra các opcodes của máy gọi chính xác.
Tony Delroy

2
"Vì mã được kết nối tại thời điểm biên dịch, không có bất kỳ chi phí tải thời gian chạy bổ sung nào. Mã chỉ đơn giản là ở đó." - có và không ... tất cả trong hình ảnh thực thi đã sẵn sàng để được phân trang nếu thực thi yêu cầu, nhưng - bắt đầu từ một tình huống mà chương trình của bạn không chạy gần đây để có trong bộ đệm - với các thư viện dùng chung có thể (đôi khi có khả năng hoặc chắc chắn) rằng HĐH, trình điều khiển hoặc chương trình đang chạy khác đã tải cùng thư viện chia sẻ mà ứng dụng của bạn muốn sử dụng, trong trường hợp đó, nó có thể nằm trong bộ đệm và chương trình của bạn khởi động và chạy nhanh hơn.
Tony Delroy

15
Điều mà một số người đã không đề cập đến là với các thư viện tĩnh, trình biên dịch biết chức năng nào mà ứng dụng của bạn cần và sau đó có thể tối ưu hóa nó bằng cách chỉ bao gồm các chức năng đó. Điều này có thể cắt giảm kích thước thư viện một cách ồ ạt, đặc biệt nếu bạn chỉ sử dụng một tập hợp con thực sự nhỏ của một thư viện thực sự lớn!
jduncanator

1
Câu trả lời này có thể được tổ chức tốt hơn. Sẽ rất hữu ích khi tạo danh sách dấu đầu dòng cho ưu / nhược điểm hoặc bảng để hiển thị sự khác biệt trong từng thứ nguyên nơi có sự khác biệt.
ElefEnt

377

Thư viện tĩnh giống như một hiệu sách và thư viện dùng chung giống như ... thư viện. Với cái trước, bạn có được bản sao của cuốn sách / chức năng để mang về nhà; sau đó bạn và mọi người khác đến thư viện để sử dụng cùng một cuốn sách / chức năng. Vì vậy, bất cứ ai muốn sử dụng thư viện (chia sẻ) cần phải biết nó ở đâu, bởi vì bạn phải "đi lấy" sách / chức năng. Với một thư viện tĩnh, cuốn sách / chức năng là của riêng bạn và bạn giữ nó trong nhà / chương trình của bạn, và một khi bạn có nó, bạn không quan tâm đến nơi nào hoặc khi nào bạn có nó.


70

Giản thể:

  • Liên kết tĩnh: một thực thi lớn
  • Liên kết động: một tệp thực thi nhỏ cộng với một hoặc nhiều tệp thư viện (tệp dll trên Windows, .so trên Linux hoặc .dylib trên macOS)

1
Câu trả lời này là tốt nhất cho tôi vì nó thực tế. Nó có ý nghĩa hơn nhiều so với một phép ẩn dụ không nói về những gì đang thực sự xảy ra trong máy tính. Sau khi biết rằng đây là những gì xảy ra, tôi chỉ bằng trực giác biết tất cả những hàm ý khác.
off99555

36

Đối với một thư viện tĩnh, mã được trích xuất từ ​​thư viện bởi trình liên kết và được sử dụng để xây dựng tệp thực thi cuối cùng tại điểm bạn biên dịch / xây dựng ứng dụng của bạn. Việc thực thi cuối cùng không có phụ thuộc vào thư viện trong thời gian chạy

Đối với thư viện dùng chung, trình biên dịch / trình liên kết kiểm tra xem tên bạn liên kết có tồn tại trong thư viện khi ứng dụng được xây dựng không, nhưng không chuyển mã của chúng vào ứng dụng. Trong thời gian chạy, thư viện chia sẻ phải có sẵn.

Bản thân ngôn ngữ lập trình C không có khái niệm về thư viện tĩnh hoặc thư viện chung - chúng hoàn toàn là một tính năng triển khai.

Cá nhân, tôi thích sử dụng các thư viện tĩnh hơn, vì nó làm cho việc phân phối phần mềm đơn giản hơn. Tuy nhiên, đây là một ý kiến ​​về việc nhiều máu (nghĩa bóng) đã được đổ ra trong quá khứ.


5
+1 cho "Bản thân ngôn ngữ lập trình C không có khái niệm về thư viện tĩnh hoặc thư viện chung - chúng hoàn toàn là một tính năng triển khai."
Tiger

1
Xin chào anon / @Tiger, tại sao bạn lại tuyên bố "Bản thân ngôn ngữ lập trình C không có khái niệm về thư viện tĩnh hoặc thư viện chung - chúng hoàn toàn là một tính năng triển khai."? Bạn có thể vui lòng giải thích một chút chi tiết hoặc chỉ cho tôi tham khảo thích hợp?
Sunil Shahu

@SunilShahu Cách chương trình được biên dịch và liên kết cụ thể với trình biên dịch và trình liên kết bạn đang sử dụng, tức là việc triển khai cụ thể ngôn ngữ. Các đặc điểm ngôn ngữ nói chung không mô tả cách các ngôn ngữ nên được thực hiện hoặc xây dựng, chỉ có chức năng, cú pháp, ngữ pháp, v.v.
JC Rocamonde

@SunilShahu ví dụ rõ ràng hơn có thể là JavaScript, ví dụ, trong đó đặc tả (EcmaScript) mô tả các tính năng của ngôn ngữ, nhưng đó là các nhà cung cấp khác nhau cung cấp trình thông dịch JS (ví dụ: công cụ trình duyệt hoặc Node.js). Mặt khác, Ngôn ngữ lập trình Python có một số triển khai. Bản chính thức là CPython, nhưng có những bản khác được viết bằng các ngôn ngữ khác.
JC Rocnhoe

31

Thư viện tĩnh được biên dịch như một phần của ứng dụng, trong khi thư viện dùng chung thì không. Khi bạn phân phối một ứng dụng phụ thuộc vào các libaries được chia sẻ, các thư viện, vd. dll trên MS Windows cần được cài đặt.

Ưu điểm của thư viện tĩnh là không có phụ thuộc cần thiết cho người dùng đang chạy ứng dụng - ví dụ: họ không phải nâng cấp DLL của họ bất cứ điều gì. Nhược điểm là ứng dụng của bạn có kích thước lớn hơn vì bạn đang vận chuyển nó với tất cả các thư viện cần thiết.

Cùng với việc dẫn đến các ứng dụng nhỏ hơn, các thư viện dùng chung cung cấp cho người dùng khả năng sử dụng phiên bản thư viện của riêng họ, có lẽ tốt hơn thay vì dựa vào một phần của ứng dụng


3
DLL địa ngục như đã được biết đến
gheese

1
"Thư viện tĩnh được biên dịch như một phần của ứng dụng" ... thư viện tĩnh được biên dịch dưới dạng thư viện tĩnh và được liên kết như một phần của ứng dụng
idclev 463035818

19

Ưu điểm đáng kể nhất của các thư viện dùng chung là chỉ có một bản sao mã được tải trong bộ nhớ, bất kể có bao nhiêu quá trình đang sử dụng thư viện. Đối với các thư viện tĩnh, mỗi tiến trình sẽ có bản sao mã riêng. Điều này có thể dẫn đến lãng phí bộ nhớ đáng kể.

OTOH, một lợi thế của các thư viện tĩnh là mọi thứ được gói vào ứng dụng của bạn. Vì vậy, bạn không phải lo lắng rằng khách hàng sẽ có thư viện (và phiên bản) phù hợp có sẵn trên hệ thống của họ.


1
hình ảnh thực thi lớn hơn trên đĩa, cũng như trong bộ nhớ, khi sử dụng libs tĩnh.
JustJeff

Đúng vậy, đó là những gì tôi đã ám chỉ khi tôi nói mọi thứ được gói vào ứng dụng của bạn.
Jasmeet

Ngoài ra, .socác tệp trên hệ thống * nix là thư viện được chia sẻ (động).
snr

6

Trên tất cả các câu trả lời khác, một điều chưa được đề cập đến là tách rời:

Hãy để tôi nói về một mã sản xuất trong thế giới thực, mà tôi đã xử lý:

Một phần mềm rất lớn, được tạo từ> 300 dự án (có studio trực quan), chủ yếu được xây dựng dưới dạng lib tĩnh và cuối cùng tất cả liên kết với nhau trong một thực thi lớn, bạn kết thúc với các vấn đề sau:

-Thời gian liên kết cực kỳ dài. Bạn có thể kết thúc sau hơn 15 phút liên kết, giả sử 10 giây thời gian biên dịch -Một số công cụ nằm trên đầu gối của họ với một công cụ thực thi lớn như vậy, như các công cụ kiểm tra bộ nhớ phải ghi mã. Bạn có thể rơi vào những giới hạn được coi là những kẻ ngốc.

Vấn đề hơn là việc tách phần mềm của bạn: trên ví dụ trong thế giới thực này, các tệp tiêu đề của mọi dự án có thể truy cập được từ bất kỳ dự án nào khác. Kết quả là, cực kỳ dễ dàng cho một nhà phát triển để thêm phụ thuộc; nó chỉ là về việc bao gồm tiêu đề, bởi vì liên kết ở cuối sẽ tìm thấy tất cả các biểu tượng. Nó kết thúc bởi sự phụ thuộc khủng khiếp đi xe đạp và lộn xộn hoàn toàn.

Với thư viện dùng chung, đó là một chút công việc phụ vì nhà phát triển phải chỉnh sửa hệ thống xây dựng dự án để thêm thư viện phụ thuộc. Tôi quan sát thấy rằng mã thư viện dùng chung có xu hướng cung cấp API mã sạch hơn.


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  |                                     |
-------------------------------------------------------------------------
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.