Việc liên kết và tải các thư viện động cả hai xảy ra khi chạy là gì? hoặc chỉ tải thư viện diễn ra vào thời gian chạy?Sự khác biệt giữa liên kết và tải bằng ngôn ngữ c
Trả lời
Xem điểm rất tốt trước đó về sự khác biệt giữa liên kết tĩnh và liên kết động. Giả sử bạn đang đề cập đến liên kết động, sau đó:
Liên kết tải và (động) được thực hiện bởi trình liên kết - trên linux và các Unix khác được thực hiện bởi /lib/ld.so
, là chương trình thực tế được khởi chạy bởi hệ điều hành trong hầu hết các trường hợp. ld.so
lần lượt tải đơn đăng ký của bạn - mygameBinary
vào bộ nhớ và ld.so
sau đó đọc từ tệp mygameBinary
danh sách thư viện được liên kết động yêu cầu.
Trình liên kết, ld.so
, sau đó tải từng thư viện này vào bộ nhớ, ví dụ: libc.so
, libpthread.so
, libopengl.so
và xem các thư viện khác các số này có thể yêu cầu, ví dụ: libm.so
.
Khi tải được thực hiện, sau đó nối bắt đầu, một quá trình xem xét các đối tượng hoặc chức năng mà là xuất khẩu bởi một thư viện hay các ứng dụng, và nhập khẩu bởi một thư viện hoặc ứng dụng có tên. Trình liên kết sau đó thay đổi các tham chiếu khác nhau và đôi khi mã để cập nhật các con trỏ dữ liệu chưa được liên kết và các cuộc gọi hàm trong mỗi thư viện để trỏ đến nơi dữ liệu hoặc chức năng thực tế cư trú. Ví dụ: cuộc gọi tới printf
trong mygameBinary
bắt đầu không trỏ đến gì (thực ra nó chỉ gọi trình liên kết), nhưng sau khi liên kết trở thành một bước nhảy tới hàm printf
trong libc
.
Sau khi liên kết này hoàn tất, ứng dụng được bắt đầu, bằng cách gọi hàm _start
trong mygameBinary
, sau đó gọi main
và trò chơi của bạn bắt đầu.
động liên kết theo cách này là cần thiết để hỗ trợ như sau:
- cập nhật thư viện sau khi ứng dụng được phát hành, trong đó thay đổi vị trí của các chức năng và dữ liệu.
- ứng dụng duy nhất chạy trên các phiên bản khác nhau của hệ điều hành
- sự không chắc chắn về nơi thư viện hoặc ứng dụng có thể được nạp vào bộ nhớ
- giảm kích thước của lõi bằng cách chia sẻ ram vật lý được sử dụng bởi các thư viện giữa nhiều ứng dụng.
Một số hệ điều hành khác nhau về chi tiết, ví dụ OSX và AIX cả tải trước một bộ thư viện nhất định vào vị trí cố định trong bộ nhớ. Điều này có nghĩa là họ không cần phải tải, chỉ cần liên kết, có thể nhanh hơn.
Một số hệ điều hành như OSX và đôi khi Linux hỗ trợ liên kết trước, đây là quá trình trong đó một tập lệnh chạy trên các ứng dụng trên hệ thống của bạn trước khi bạn khởi chạy chúng và thực hiện liên kết.Khi bạn khởi động chúng, bạn không cần phải liên kết chúng. Điều này quan trọng vì liên kết mất một lượng thời gian máy tính đáng kể khi bạn khởi chạy ứng dụng và một số ứng dụng có thể được khởi chạy nhiều lần trong một giây, chẳng hạn như gcc
, cpp
và as
trong quá trình xây dựng ứng dụng hoặc lọc tập lệnh khi lập chỉ mục dữ liệu máy tính của bạn (OSX Spotlight).
Liên kết là quá trình thực hiện một số tệp thực thi nhỏ hơn và kết hợp chúng với nhau dưới dạng tệp thực thi lớn hơn.
Đang tải đang tải tệp thi hành vào bộ nhớ trước khi thực thi.
Anh ấy hỏi về thư viện động, trong đó trường hợp liên kết không phải là quá trình bao gồm "thực thi" nhỏ hơn trong một tệp lớn hơn. – tgamblin
Cả hai xảy ra khi chạy cho thư viện động.
Đầu tiên, các thư viện được tải cùng với tất cả các phụ thuộc của chúng (và các phụ thuộc của các thư viện đó, v.v.). Sau đó, trình liên kết động giải quyết các ký hiệu trong các thư viện được tải. Thông thường cả hai chức năng này đều được thực hiện bởi cùng một phần mềm; trên Linux là ld.so.
Ký hiệu trong thư viện tĩnh được giải quyết tại thời gian liên kết và được bao gồm trong tệp thực thi. Tuy nhiên, các thư viện tĩnh có các biểu tượng chưa được giải quyết thỏa mãn khi chạy theo thư viện động.
Có mô tả chuyên sâu về cách điều này xảy ra, cách các tên được băm, cách tốn kém để giải quyết các biểu tượng trong thời gian chạy, v.v. trong How to Write Shared Libraries.
Có hai loại liên kết: liên kết tĩnh và liên kết động.
Liên kết tĩnh xảy ra tại thời gian biên dịch, do đó nó xảy ra trước khi tải chương trình. Với liên kết tĩnh các ký hiệu bên ngoài được chương trình của bạn sử dụng (ví dụ: tên hàm) được giải quyết tại thời gian biên dịch.
Liên kết động xảy ra vào thời gian chạy, vì vậy nó xảy ra sau hoặc tại thời điểm tải chương trình. Với liên kết động các biểu tượng được giải quyết hoặc tại thời gian tải, hoặc tại thời gian chạy khi biểu tượng được truy cập (ràng buộc lười). Sau này là phổ biến hơn.
Hệ thống Windows và Unix sử dụng các phương pháp tiếp cận hoàn toàn khác với Thư viện động.
Windows DLL không được liên kết. Do đó, bạn không thể chia sẻ các đối tượng tĩnh trên các tệp DLL. Nó giống như một chương trình riêng biệt trong không gian địa chỉ của bạn.
Đối tượng được chia sẻ Unix thực sự "được liên kết" trong thời gian chạy, giống như các mô-đun khác nhau của cùng một dự án, thực hiện độ phân giải biểu tượng.
Không chính xác, Windows DLL được liên kết và có thể chia sẻ dữ liệu. –
nobugz: Tôi đề nghị bạn tra cứu mục "liên kết" và cách hoạt động của độ phân giải biểu tượng. Bạn sẽ thấy tại sao không có cách nào để chia sẻ một biến tĩnh trên ranh giới DLL. –
Cả tải liên kết động và thư viện diễn ra vào lúc chạy, nhưng liên kết động được thực hiện trước khi thực hiện chương trình và được thực hiện bởi trình liên kết hệ thống. Vì vậy, ví dụ, nếu thư viện bắt buộc bị thiếu, chương trình không thể được thực hiện. Tải thư viện, mặt khác, được thực hiện bởi chính chương trình, thông qua các chức năng dlopen/LoadLibrary. Trong trường hợp này, quá trình tải được kiểm soát bởi ứng dụng, có thể, ví dụ như xử lý lỗi.
vì vậy khi nào tải xảy ra sau đó? Là nó trước khi giai đoạn liên kết (trong trường hợp liên kết động) – Vijay
Trong trường hợp tải, thư viện được nạp khi chương trình gọi dlopen/LoadLibrary chức năng. Nó có thể xảy ra bất cứ khi nào lập trình viên muốn;) –
file01.c, file02.c -> produce -> file01.o, file02.o -> Những thông tin .o này được gắn vào và đưa vào một thư viện động duy nhất, đó là lib1.a tệp11. c, file12.c -> sản xuất -> file11.o, file12.o -> Những thông tin .o này được gắn và đặt vào một thư viện động duy nhất, đó là lib2.a
Bây giờ, tôi có 2 các thư viện cuối cùng được liên kết với nhau để tạo ra tệp thực thi (như .elf hoặc .mot hoặc .fls). Quá trình liên kết thông tin này từ lib1.a và lib2.a để tạo thành một tệp thực thi duy nhất được gọi là liên kết.
Bây giờ, tôi cần tải bộ nhớ này vào bộ nhớ để chạy nó để xem hành vi của tệp thực thi cuối cùng. Quá trình tải tệp thực thi cuối cùng (như .elf hoặc .mot hoặc .fls) vào bộ nhớ để chạy được gọi là tải.
Tôi hy vọng điều này sẽ xóa tầm quan trọng của việc liên kết và tải (tuy nhiên các định nghĩa không phù hợp :-)).
tôi biết quá trình liên kết và tải ... những gì tôi cần là một trong số chúng sẽ xảy ra trước tiên và tại sao? – Vijay
Đó chắc chắn là liên kết xảy ra trước ... cho chúng ta thực thi cuối cùng ... mà sau đó được tải để thực thi ... để liên kết đầu tiên, tiếp theo là tải ... bằng cách này, xin lỗi vì phản hồi bị trì hoãn. .. :-) – wrapperm
- 1. Sự khác biệt giữa% d và% * d trong ngôn ngữ c là gì?
- 2. Sự khác biệt giữa ngôn ngữ C và Posix trên Postgres là gì?
- 3. Sự khác biệt về ngôn ngữ hội (MIPS) và thêm
- 4. Sự khác biệt giữa lập trình đa lõi trong Erlang và ngôn ngữ khác là gì?
- 5. Sự khác biệt giữa trình liên kết động và trình tải động là gì?
- 6. Sự khác biệt giữa Clustering và cân bằng tải?
- 7. Sự khác biệt giữa ngôn ngữ theo định hướng thành phần và ngôn ngữ hướng đối tượng là gì?
- 8. Sự khác nhau giữa cú pháp và ngữ nghĩa của ngôn ngữ lập trình là gì?
- 9. Sự khác biệt giữa ASP.NET và C# là gì?
- 10. Sự khác biệt giữa ngôn ngữ lập trình hàm và mệnh lệnh là gì?
- 11. Sự khác biệt giữa các ngôn ngữ gõ mạnh và yếu?
- 12. Sự khác biệt giữa liên kết động thời gian tải và liên kết động thời gian chạy
- 13. C++ - Sự khác biệt giữa (*). và ->?
- 14. Sự khác biệt giữa C++ 11 std :: liên kết và tăng :: ràng buộc
- 15. Sự khác biệt giữa các khai báo "kiểu tập lệnh" và "ngôn ngữ kịch bản"
- 16. Sự khác biệt giữa = và: =
- 17. Sự khác biệt giữa destructor và finalizer?
- 18. Sự khác biệt giữa NLS_UPPER và UPPER
- 19. sự khác biệt giữa -lgcc_s và gcc
- 20. Sự khác biệt giữa Điểm kết nối NTFS và Liên kết tượng trưng là gì?
- 21. Sự khác biệt giữa $ @ và $! trong perl
- 22. Sự khác biệt giữa Agda và Idris
- 23. Sự khác biệt giữa cấu trúc trong C và C++
- 24. Sự khác biệt giữa ipa và xcarchive
- 25. Sự khác biệt giữa Dispatcher.BeginInvoke và Task.Factory.StartNew
- 26. Sự khác biệt ngữ nghĩa giữa lưu/ghi/lưu trữ và đọc/tải?
- 27. Tại sao có sự khác biệt giữa các ngôn ngữ lắp ráp như Windows, Linux?
- 28. Sự khác biệt giữa Turing-Decidable và Co-Turing-Decidable
- 29. Sự khác biệt giữa trình biên dịch và trình liên kết là gì?
- 30. Sự khác biệt giữa 'cam kết' và 'sửa đổi'
http://stackoverflow.com/questions/311882/what-do-statically-linked-and-dynamically-linked-mean/311889#311889 – paxdiablo
đó không phải là bản sao chính xác –