2009-05-27 36 views
153

Tôi biết rất ít về DLL và LIB khác hơn là chúng chứa mã quan trọng cần thiết cho một chương trình để chạy đúng - thư viện. Nhưng tại sao các trình biên dịch lại tạo ra chúng? Nó sẽ không được dễ dàng hơn để chỉ bao gồm tất cả các mã trong một tập tin thực thi duy nhất? Và sự khác biệt giữa DLL và LIB là gì?Tệp DLL và LIB - điều gì và tại sao?

Trả lời

220

Có các thư viện tĩnh (LIB) và thư viện động (DLL).

Thư viện được sử dụng vì bạn có thể có mã mà bạn muốn sử dụng trong nhiều chương trình. Ví dụ: nếu bạn viết một hàm đếm số ký tự trong một chuỗi, hàm đó sẽ hữu ích trong nhiều chương trình. Khi bạn nhận được hàm đó hoạt động chính xác, bạn không muốn phải biên dịch lại mã mỗi khi bạn sử dụng nó, vì vậy bạn đặt mã thực thi cho hàm đó trong thư viện và trình liên kết có thể trích xuất và chèn mã được biên dịch vào chương trình của bạn . Các thư viện tĩnh đôi khi được gọi là 'lưu trữ' vì lý do này.

Thư viện động tiến thêm một bước nữa. Có vẻ như lãng phí khi có nhiều bản sao của các chức năng thư viện chiếm dung lượng trong mỗi chương trình. Tại sao tất cả họ không thể chia sẻ một bản sao của chức năng? Đây là thư viện động. Thay vì xây dựng mã thư viện vào chương trình của bạn khi nó được biên dịch, nó có thể được chạy bằng cách ánh xạ nó vào chương trình của bạn khi nó được nạp vào bộ nhớ. Nhiều chương trình chạy cùng một lúc sử dụng cùng chức năng có thể chia sẻ một bản sao, lưu bộ nhớ. Trong thực tế, bạn chỉ có thể tải thư viện động khi cần thiết, tùy thuộc vào đường dẫn thông qua mã của bạn. Không có điểm trong việc có thói quen máy in chiếm bộ nhớ nếu bạn không thực hiện bất kỳ thao tác in nào. Mặt khác, điều này có nghĩa là bạn phải có một bản sao của thư viện động được cài đặt trên mọi máy mà chương trình của bạn chạy. Điều này tạo ra một tập hợp các vấn đề riêng. Ví dụ, hầu như mọi chương trình được viết bằng 'C' sẽ cần các hàm từ thư viện được gọi là thư viện 'C runtime', mặc dù một vài chương trình sẽ cần tất cả các chức năng. Thời gian chạy C có cả phiên bản tĩnh và động, vì vậy bạn có thể xác định phiên bản chương trình của bạn sử dụng tùy thuộc vào nhu cầu cụ thể.

+49

Chỉ ra rằng tệp '.LIB' có thể là thư viện tĩnh (chứa tệp đối tượng) hoặc thư viện nhập (chứa biểu tượng để cho phép trình liên kết liên kết đến tệp DLL). [Tôi tự hỏi tại sao điều này là như vậy.] (Http://stackoverflow.com/q/6421693/269126) – Lumi

+1

giải thích tốt! Mã được chia sẻ và dữ liệu (theo mặc định) không được chia sẻ giữa (các) ứng dụng tiêu thụ một Dll. – mox

10

Một lý do quan trọng để tạo DLL/LIB thay vì chỉ biên dịch mã thành một tệp thực thi là tái sử dụng và di chuyển. Ứng dụng Java hoặc .NET trung bình (ví dụ) sẽ rất có thể sử dụng một số thư viện của bên thứ ba (hoặc khung công tác). Việc biên dịch một thư viện được xây dựng sẵn dễ dàng hơn và nhanh hơn, thay vì phải biên dịch tất cả mã của bên thứ 3 vào ứng dụng của bạn. Việc biên dịch mã của bạn thành các thư viện cũng khuyến khích thực hành thiết kế tốt, ví dụ: thiết kế các lớp học của bạn để được sử dụng trong các loại ứng dụng khác nhau.

24

Một khía cạnh khác là bảo mật (obfuscation). Khi một đoạn mã được trích xuất từ ​​ứng dụng chính và đưa vào Thư viện liên kết động "tách biệt", sẽ dễ dàng tấn công, phân tích mã ngược hơn vì nó đã bị cô lập. Khi cùng một đoạn mã được lưu giữ trong Thư viện LIB, nó là một phần của ứng dụng đích được biên dịch (liên kết), và do đó khó phân biệt đoạn mã đó với phần còn lại của các tệp nhị phân đích.

+0

Khía cạnh bảo mật mới đối với tôi. Có phải lý do trên giữ đúng trong trường hợp của một ứng dụng C# gọi một native C++ dll không được quản lý? – Martin

+0

Nhưng LIB cũng bị cô lập, phải không? Vì vậy, một Kẻ tấn công có thể chỉ đơn giản là phân tích LIB. Hay là một kịch bản phổ biến mà LIB không thể truy cập công khai? –

+3

LIB cũng "bị cô lập", khi quá trình biên dịch được quan tâm, nhưng một khi trình liên kết đưa các phần vào nhau, LIB là một phần của EXE và không thể phân biệt với mã của riêng bạn. – mox

7

DLL là thư viện các hàm được chia sẻ giữa các chương trình thực thi khác. Chỉ cần nhìn vào cửa sổ của bạn/system32 thư mục và bạn sẽ tìm thấy hàng chục người trong số họ. Khi chương trình của bạn tạo ra một tệp DLL, nó cũng thường tạo một tệp lib để chương trình * .exe có thể giải quyết các biểu tượng được khai báo trong DLL.

A .lib là thư viện các hàm được liên kết tĩnh với chương trình - chúng KHÔNG được chia sẻ bởi các chương trình khác. Mỗi chương trình liên kết với tệp * .lib có tất cả mã trong tệp đó. Nếu bạn có hai chương trình A.exe và B.exe liên kết với C.lib thì mỗi A và B sẽ chứa cả hai mã trong C.lib.

Cách bạn tạo tệp DLL và lib phụ thuộc vào trình biên dịch bạn sử dụng. Mỗi trình biên dịch thực hiện nó một cách khác nhau.

2

Một khác biệt khác nằm ở hiệu suất.

Khi tệp DLL được tải khi chạy bởi .exe (s), .exe (s) và DLL làm việc với khái niệm bộ nhớ dùng chung và do đó hiệu suất thấp tương đối với liên kết tĩnh.

Mặt khác, .lib là mã được liên kết tĩnh tại thời gian biên dịch vào mọi quá trình yêu cầu. Do đó .exe (s) sẽ có bộ nhớ duy nhất, do đó tăng hiệu suất của quá trình.

Các vấn đề liên quan