2010-07-29 33 views
26

Trước ngày hôm nay, tôi luôn tin rằng thứ tự các đối tượng và thư viện được chuyển tới g ++ trong giai đoạn liên kết không quan trọng. Sau đó, hôm nay, tôi đã thử liên kết từ mã C++ đến mã c. Tôi bọc tất cả các tiêu đề C trong một khối "C" bên ngoài nhưng mối liên kết vẫn gặp khó khăn khi tìm các biểu tượng mà tôi biết là trong kho lưu trữ đối tượng C.g ++ liên kết phụ thuộc thứ tự khi liên kết mã c tới mã C++

Khó hiểu, tôi đã tạo một ví dụ tương đối đơn giản để tách biệt lỗi liên kết nhưng tôi ngạc nhiên, ví dụ đơn giản được liên kết mà không gặp bất kỳ sự cố nào.

Sau một chút thử và lỗi, tôi thấy rằng bằng cách mô phỏng mẫu liên kết được sử dụng trong ví dụ đơn giản, tôi có thể lấy mã chính để liên kết OK. Các mô hình đã được mã đối tượng đầu tiên, đối tượng tài liệu lưu trữ thứ hai ví dụ:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

bất cứ ai có thể làm sáng tỏ về lý do tại sao có thể như vậy ?. Tôi chưa bao giờ thấy vấn đề này khi liên kết mã C++ bình thường.

+0

Để biết chi tiết, hãy xem: http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference -to-vtable-cho-xxx-undefined-referen/1095321 # 1095321 –

Trả lời

35

Thứ tự bạn chỉ định tệp và thư viện đối tượng là rất quan trọng trong GCC - nếu bạn chưa bị cắn bởi điều này trước khi bạn có một cuộc sống quyến rũ. Trình liên kết tìm kiếm các biểu tượng theo thứ tự chúng xuất hiện, vì vậy nếu bạn có tệp nguồn chứa cuộc gọi đến hàm thư viện, bạn cần đặt nó trước thư viện hoặc trình liên kết sẽ không biết rằng nó phải giải quyết nó. Việc sử dụng thư viện phức tạp có thể có nghĩa là bạn phải chỉ định thư viện nhiều lần, đó là một nỗi đau của hoàng gia để có được quyền.

+0

Tin tôi đi, tôi chưa :-), có tài liệu nào về tài sản này không? –

+0

Ở đây chúng tôi đi: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html –

+0

Tôi cũng đã luôn tìm thấy thứ tự liên kết quan trọng; cũng khó có thể giải thích tại sao các lỗi liên kết cũng xảy ra, cho đến khi bạn đoán rằng thứ tự sai ... –

6

Thư viện tĩnh là tập hợp các tệp đối tượng được nhóm thành một tệp lưu trữ. Khi liên kết với nó, trình liên kết chỉ chọn các đối tượng cần thiết để giải quyết bất kỳ biểu tượng nào chưa được xác định. Vì các đối tượng được liên kết theo thứ tự được đưa ra trên dòng lệnh, các đối tượng từ thư viện sẽ chỉ được bao gồm nếu thư viện xuất hiện sau tất cả các đối tượng phụ thuộc vào nó.

Vì vậy, thứ tự liên kết rất quan trọng; nếu bạn định sử dụng các thư viện tĩnh, thì bạn cần phải cẩn thận để theo dõi các phụ thuộc và không giới thiệu các phụ thuộc tuần hoàn giữa các thư viện.

+0

Các phụ thuộc tuần hoàn là OK - nó chỉ có nghĩa là bạn cần có một đường liên kết như "' ao bo ao' ". – caf

+1

@caf: nếu các đối tượng bổ sung từ sự bao gồm thứ hai của 'a' phụ thuộc vào các đối tượng trong' b' chưa được đưa vào, thì điều đó không đủ tốt; bạn sẽ cần phải thêm 'b' một lần nữa vào cuối. Mà lần lượt có thể giới thiệu thêm phụ thuộc vào 'a'. Vì vậy, phụ thuộc theo chu kỳ không thực sự "OK", nó chỉ hiếm hoi cho họ để được bệnh lý đủ để cần nhiều hơn một sự lặp lại. –

17

Thứ tự thư viện chuyển đến gcc/g ++ thực sự quan trọng. Nếu A phụ thuộc vào B, A phải được liệt kê trước. Lý do là nó tối ưu hóa các biểu tượng không được tham chiếu, vì vậy nếu nó thấy thư viện B trước tiên, và không ai đã tham chiếu nó vào thời điểm đó thì nó sẽ không liên kết bất kỳ thứ gì từ nó.

0

Bạn có thể sử dụng tài liệu lưu trữ --start nhóm --end nhóm và viết 2 thư viện phụ thuộc thay vì tài liệu lưu trữ

gcc main.o -L. -Wl, - nhóm bắt đầu -lobj_A -lobj_b -Wl, - nhóm cuối

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