2009-12-23 21 views

Trả lời

14

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, cppas 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).

6

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.

+1

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

1

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.

3

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.

-1

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.

+0

Không chính xác, Windows DLL được liên kết và có thể chia sẻ dữ liệu. –

+0

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. –

-1

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.

+0

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

+0

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;) –

0

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 :-)).

+0

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

+0

Đó 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

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