2010-01-08 19 views
14

Tôi có một C + + thực thi và tôi đang tự động liên kết với một số thư viện (Boost, Xerces-c và tùy chỉnh libs).Tại sao trình liên kết C++ yêu cầu tệp thư viện trong khi xây dựng, mặc dù tôi đang liên kết động?

Tôi hiểu tại sao tôi yêu cầu tệp .lib/.a nếu tôi chọn liên kết tĩnh với các thư viện này (relevant SO question here). Tuy nhiên, tại sao tôi cần phải cung cấp tệp thư viện .lib/.so tương ứng khi liên kết tệp thực thi của tôi nếu tôi đang tự động liên kết với các thư viện bên ngoài này?

+2

Trình liên kết cần biết * * DLL nào chứa một xuất mà nó cần phải giải quyết. Tệp .lib cung cấp thông tin này. –

Trả lời

8

Trình biên dịch không nhận thức được liên kết động, nó chỉ biết rằng một hàm tồn tại thông qua nguyên mẫu của nó. Trình liên kết cần các tệp lib để giải quyết biểu tượng. Các lib cho một DLL chứa thông tin bổ sung như những gì DLL các chức năng sống và làm thế nào chúng được xuất khẩu (theo tên, theo thứ tự, vv) Các tập tin lib cho DLL chứa thông tin ít hơn nhiều so với các tập tin lib có chứa mã đối tượng đầy đủ - libcmmt .lib trên hệ thống của tôi là 19,2 MB, nhưng msvcrt.lib là "chỉ" 2,6 MB.

Lưu ý rằng mô hình biên dịch/liên kết này đã gần 40 tuổi vào thời điểm này và trước khi liên kết động trên hầu hết các nền tảng. Nếu nó được thiết kế ngày hôm nay, liên kết động sẽ là một công dân hạng nhất (ví dụ, trong .NET, mỗi assembly có siêu dữ liệu phong phú mô tả chính xác những gì nó xuất khẩu, vì vậy bạn không cần tiêu đề và lib riêng biệt.)

+3

Vì vậy, nếu tôi hiểu điều này một cách chính xác: Là một thay thế cho 'ngầm' liên kết động (liên kết với .lib trong khi xây dựng, sử dụng DLL lúc chạy) - Tôi có thể 'rõ ràng' liên kết lúc chạy bằng cách sử dụng (trên Windows) LoadLibrary() để tải DLL và GetProcAddress() để trả về một con trỏ hàm đến phương thức mà tôi đang gọi. Đó là nhiều mã để viết, nhưng tôi sẽ không cần .lib lúc xây dựng. –

+0

Hiểu biết của bạn là chính xác. – Michael

1

một điều, trình liên kết chèn các phiên bản của các thư viện tồn tại ở thời gian liên kết để bạn có một số cơ hội của chương trình làm việc nếu các phiên bản thư viện được cập nhật. Nhiều phiên bản của thư viện được chia sẻ có thể tồn tại trên một hệ thống.

1

Trình liên kết có công việc xác thực rằng tất cả các ký hiệu không xác định của bạn được tính, có nội dung tĩnh hoặc nội dung động.

Theo mặc định, sau đó, nó khẳng định trên tất cả các biểu tượng của bạn đang có mặt.

Tuy nhiên, đó chỉ là mặc định. Xem -z và --allow-shlib-undefined và bạn bè.

0

Có lẽ liên kết động này được thực hiện qua thư viện nhập (hàm có __declspec (dllimport) trước định nghĩa).
Nếu đây là cách so với máy tính tổng hợp dự kiến ​​có hàm __imp_symbol được khai báo và hàm này chịu trách nhiệm chuyển tiếp cuộc gọi đến đúng thư viện được tải động.
Các chức năng này được tạo trong khi liên kết các biểu tượng với từ khóa __declspec (dllimport)

2

Raymond Chen đã viết một vài mục blog về điều này cụ thể cho Windows. Bắt đầu với The classical model for linking và sau đó theo dõi với Why do we have import libraries anyway?.

Để tóm tắt, lịch sử đã xác định trình biên dịch là thành phần biết về thông tin loại chi tiết, trong khi trình liên kết chỉ biết về tên biểu tượng. Do đó, trình liên kết kết thúc bằng việc tạo ra .DLL mà không có thông tin kiểu, và do đó các chương trình muốn liên kết với nó cần một số loại siêu dữ liệu để nói về cách các hàm được xuất và kiểu tham số nào chúng lấy và trả về.

Lý do .DLL không có tất cả thông tin bạn cần để liên kết trực tiếp với họ là lịch sử chứ không phải là giới hạn kỹ thuật.

0

Dưới đây là mô tả rất SIMPLIFIED có thể hữu ích. Liên kết tĩnh đặt tất cả mã cần thiết để chạy chương trình của bạn vào tệp thi hành để mọi thứ được tìm thấy. Liên kết động nghĩa là một số mã được yêu cầu không được đưa vào tệp thực thi và sẽ được tìm thấy trong thời gian chạy. Tôi tìm thấy nó ở đâu? Hàm x() có ở đó không?Làm thế nào để thực hiện cuộc gọi đến hàm x()? Đó là những gì thư viện nói với trình liên kết khi bạn đang liên kết động.

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